Java虚拟机的内存区域

1.引言

我们知道虚拟机的自动内存管理机制帮我们简化了代码,不容易出现内存泄漏和内存溢出的问题。但是一旦出现了内存泄露的问题,如果不了解虚拟机是怎么使用内存,那么排查错误将会是一项异常艰难的工作。

2.运行时数据区域

Java虚拟机的内存区域_第1张图片

2.1 程序计数器

           属性:线程私有。

作用:当前线程执行字节码的行号指示器;通俗的将就是字节码解释器工作时通过改变计数器的值选取下一条需要执行的字节码指令。分支,循环,跳转,异常处理,线程恢复等不是按照顺序执行的基础功能都依赖于程序计数器。

工作方式:如果线程正在执行一个java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址,如果正在执行一个本地方法,这个计数器的值为空。

附加:

本地方法:在Java中,有些方法涉及到与操作系统交互,获取和使用操作系统的硬件或软件的资源,单纯的用Java实现要么实现很困难,或者不能实现,这时候就要使用本地方法,本地方法就是用其他语言写的方法,然后在JVM中调用

 

2.2 java虚拟机栈

属性:线程私有;java方法的内存模型。

作用:存放每个方法执行时产生的栈帧。

工作方式:每个方法从调用直至执行完成的过程,就对应了一个栈帧在虚拟机栈中入栈到出栈的过程。如果线程请求的深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。

附加:

栈帧:储存局部变量表,操作数栈,动态链接,方法出口等信息。

局部变量表:编译后各种数据类型,对象引用,代表一个对象的句柄或其它与此对象相关的位置和returnAddress类型,运行时局部变量表的大小已经通过Class文件完全确定的,以变量槽(slot)为最小单位。

操作数栈:可以是任意一个java数据类型。当一个方法刚刚开始执行的时候,这个方法的操作数栈是空的,在方法的执行过程中,会有各种字节码指令往操作数栈中写入和提取内容。

动态链接:将栈帧所属方法的引用在每一次运行期间转化成直接引用而不是在类加载阶段或者是第一次使用的时候。

方法出口:退出方法有两种情况:1.执行引擎遇到任意一个方法返回的字节码指令称为正常完成出口。2.遇到异常称为异常返回出口。正常退出时:栈帧可能会保存PC计数器作为返回地址。异常退出时:返回的地址通过异常处理器来确定。方法退出的过程等同于把当前栈帧出栈,因此退出时可能执行的操作有:恢复上层方法的局部变量表和操作数栈,如果有返回值压入调用者栈帧的操作数栈中,调整PC计数器的值以指向方法调用指令后面的一条指令。

一般将动态链接,方法返回地址与其它附加信息全部归为一类,称为栈帧信息。

2.3本地方法栈

本地方法的作用与虚拟机栈非常相似,只是虚拟机栈执行的是java方法,而本地方法栈执行的是本地方法。有的虚拟机会将他们两二合一。

2.4 java堆

属性:线程共享;内存最大的一块区域;也是垃圾收集器管理的主要区域;

作用:存放对象实例。

工作方式:划分区域分配内存,可以分配不连续的内存空间。

2.5 方法区

属性:线程共享;内存区域;

作用:存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。

工作方式:将加载的Class文件中常量池部分存放到常量池

附加:

运行时常量池:存放编译期生成的各种字面量和符号引用以及直接引用。运行期间也可能将新的常量池放入池中。

 

2.6 执行引擎

属性:自定义指令集和执行引擎的结构体系;

作用:解析字节码。

工作方式:分为解释执行和编译执行两种不同的工作方式:

解释执行:java编译器输出字节码指令流通过解释器执行。

编译执行:通过JIT即时编译器产生本地代码执行。

 

你可能感兴趣的:(Java虚拟机的内存区域)