Java虚拟机在运行Java程序时,会将它所管理的内存划分为若干个内存区域。这些数据区域有各自的用途、以及建立和销毁时间。有的随着虚拟机启动而启动,有的区域则依赖java线程的启动和结束来创建和销毁。
Java虚拟机运行时数据区图以下(来自深刻理解Java虚拟机:jvm的高级特性和实践):
如下对运行时数据区的各个区域作相应的解释:java
程序计数器是一个较小的内存空间,能够把它看作当前线程执行的字节码时的行号指示器。字节码解释器的工做就是经过不断改变这个计数器来选择下一条须要执行的字节码指令、分支、循环等功能。
因为java的多线程是经过轮流切换线程分配处理器执行时间的方式来实现的,因此,在任何一个时间点,一个处理器只会执行一条线程中的指令。所以,为了能保证线程切换后能恢复到正确的位置,每条线程都须要有一个独立的程序计数器。各条线程计数器之间互不影响,独立存储。咱们称这类内存区域为“线程私有”的内存。
若是线程正在执行的是一个java方法,计数器记录的是虚拟机正在执行的字节码指令地址。
若是线程正在执行的是一个Native方法,这个计数器值则为空。
此内存区域是惟一一个在java虚拟机规范中没有规定任何OutOfMemoryError的状况的区域
总结:算法
与程序计数器同样,虚拟机栈也是线程私有的,它的生命周期和线程相同。虚拟机栈描述的是java方法执行的内存模型:每一个java方法在执行时都会建立一个栈帧(stack frame)用于存储局部变量表、操做数栈、动态连接、方法出口等信息。每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈出栈的过程。
总结:数据结构
本地方法栈和虚拟机栈所发挥的做用是很是类似的,只不过虚拟机栈是为java虚拟机执行java方法(字节码)而服务,而本地方法栈则是为了虚拟机中使用到的Native方法服务。
在虚拟机规范中没有明确规定本地方法栈使用的语言、数据结构没有强制约定。具体的虚拟机能够自由实现它。
总结:多线程
对于大多数应用来讲,Java堆(Heap)是java虚拟机管理的最大一块内存区域,java堆是全部线程共享的一块内存区域,会在虚拟机启动时建立。
Java堆内存的惟一目的就是:存放对象实例
因为如今收集器都采用分代收集算法,因此java堆还能够分为新生代和老年代。
总结:jvm
方法区和Java堆同样,是被全部线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等。
该区域的内存回收目标主要是针对常量池的回收和对类型的卸载
总结:spa
运行时常量池是方法区的一部分,Class文件除了有类的版本、字段、方法、接口等描述信息外。还有一项重要信息就是常量池,用于存储编译器生成的各类字面量和符号引用,这部份内容将在类加载后进入方法区的运行时常量池中。
总结:线程
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">对象