Java运行时数据区域

1、内存划分

数据存储区域,对于这一块区域的划分,各个虚拟机有各自的划分方式,不过它们都必须遵从JAVA虚拟机的基本规范去实现。

Java运行时数据区域


2、程序计数器

可以看作是当前线程所执行的字节码的指示器,即字节码解释器工作时,通过改变这个指示器的值来选取下一条需要执行的字节码指令。如:循环、跳转、异常处理、线程恢复等。Java虚拟机的多线程运行是通过轮流切换线程并分配处理器执行的时间来实现的,为了保证当线程挂起并唤醒后,可以在它原来正确的位置继续执行,因此它是线程私有的。

如果线程线程执行的是方法,计算器记录的是当正在执行的虚拟机字节码指令的地址,如果执行的是native方法,则这个计数器为空。

3、Java虚拟机栈

Java虚拟机栈也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法执行的同时会创建一个栈帧,用于存放局部变量表,操作数栈,动态链接、方法出口等信息。

局部变量表:存放了编译器可知的基本类型数据(boolean、byte、char...)、对象引用,returnAddress类型(指向了一条字节码指令的地址)。其中64位的double、long占用2个局部变量空间(Slot),其余数据类型占用1个。局部变量的内存空间在编译期就确定了,在运行期不会改变它的大小。

操作数栈:它是一个后进先出(LIFO)栈,而它的长度也是在编译时期就写入了class文件当中,是固定的。它的作用就是提供字节码指令操作变量计算的空间

4、java堆

Java堆是线程共享的一块内存区域,是Java垃圾收集器管理的主要区域。它是随着虚拟机的启动而创建,几乎所有的对象、数组都要在堆上分配。

5、方法区(永久代)

方法区是线程共享的,主要用来存储已被虚拟机加载的类信息,常量,静态变变量、即时编译器编译后的代码等。在hotspot虚拟机上,1.7以前采用永久代来管理方法区,因为永久代有-xx:MaxPermSize的上限,容易导致内存溢出。1.7以后将字符串常量池移除出了永久代,放到了本地方法区。

6、运行时常量池

常量池属于方法区的一部分。class文件在编译后,类文件中保存有类的版本、字段、方法、接口等信息,还有一个常量池,该常量池中用来保存编译期生成的字面量和符号引用,并且随着类加载后存放在方法区的运行时常量池中。

7、本地方法栈

本地方法栈用来存放虚拟机使用到的Native方法服务。Hotspot虚拟机直接把本地方法栈根虚拟机栈合二为一。