这几天从图书馆借了《深入理解Java虚拟机》,看到内存区域这一章,总结了一下。
Java虚拟机所管理的内存区域如下图所示:
其中各区域具体的作用如下
1、程序计数器
字节码解释器通过改变程序计数器的值来选取下一条要执行的字节码指令(分支、循环线程恢复等基础功能都需要依赖这个计数器);每个线程都有一个独立的程序计数器(各线程的计数器间互不影响,独立储存);此内存区域不会发生OutOfMemoryError。
2、Java虚拟机栈
虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于储存局部变量表、操作数栈、动态链接、方法出口等信息;方法从调用到执行完成的过程对应着一个栈帧在虚拟机栈中入栈到出栈的过程;局部变量表储存了编译期间可知的各种基本数据类型、对象引用、returnAddress类型(指向一条字节码指令的地址);long和double类型的数据占用两个局部变量空间,其余数据类型占用一个局部变量空间,局部变量表所需的内训空间在编译期间完成分配;虚拟机栈是线程私有的,生命周期与线程的生命周期相同。
3、本地方法栈
本地方法栈与虚拟机栈的作用相似,区别在于虚拟机栈为Java方法服务,本地方法栈为虚拟机使用到的Native方法服务。
4、Java堆
Java堆的唯一目的就是存放对象实例,几乎所有的对象实例和数组都要在堆上分配;Java堆是所有线程共享的一块内存区域;Java堆是垃圾回收器管理的主要区域,根据垃圾分代收集算法,Java堆可以细分为:新生代和老年代,在细分可以分成Eden空间、From Survivor空间、To Survivor空间等;Java堆可以处于物理上的不连续内存空间中,只要逻辑上是连续的即可。
5、方法区(Non-Heap)
方法区是线程共享的内存区域;用于储存已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
6、运行时常量池
运行时常量池是方法区的一部分;用于储存编译期生成的各种字面量和符号引用。