Java虚拟机之内存区域

Java虚拟机管理的内存包括几个运行时数据内存:方法区、虚拟机栈、堆、本地方法栈、程序计数器,其中方法区和堆是由线程共享的数据区,其他几个是线程隔离的数据区。

程序计数器:

程序计数器是一块较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器工作时通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等功能都需要依赖这个计数器来完。

另外,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。

虚拟机栈:

与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期和线程相同,描述的是Java方法执行的内存模型。

虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、数据操作、动态链接、出口方法等信息。每个方法从调用直到执行完成的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。

Java内存可以粗糙的区分为堆内存(Heap)和栈内存(Stack),其中栈就是现在说的虚拟机栈,或者说是虚拟机栈中局部变量表部分。局部变量表主要存放了编译器可知的各种数据类型、对象引用。

本地方法栈:

和虚拟机栈所发挥的作用非常相似,区别是: 虚拟机栈为虚拟机执行Java方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务。

堆:

Java虚拟机所管理的内存中最大的一块。Java堆是所有线程共享的一块内存区域,在虚拟机启动时创建。

此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例以及数组都在这里分配内存。

Java堆是垃圾收集器管理的主要区域,因此也被称作GC堆(Garbage Collected Heap)

从内存回收的角度,由于现在收集器基本都采用分代收集算法,所以Java堆还可以细分为新生代和老年代,再细致一点有Eden空间、From Survivor、To Survivor空间等。

从内容分配的角度,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区。

无论怎么划分,目的是更好地回收内存,或者更快地分配内存。

方法区:

方法区与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即使编译器编译后的代码等数据。

运行时常量池:

运行时常量池是方法区的一部分。Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有常量池信息(用于存放编译期生成的各种字面量和符号引用)。


参看文献:《深入了解Java虚拟机:JVM高级特性与最佳实践》

猜你喜欢

转载自www.cnblogs.com/leirocks/p/9154586.html