运行时数据区域
Java虚拟机在执行Java程序时会把它所管理的内存分为若干个不同的数据区域,这些区域有各自的用途,以及创建时间和销毁时间,有的区域随着虚拟机进程的启动尔存在,有的区域则依赖用户线程的启动和结束尔创建和销毁。根据Java虚拟机规范,Java虚拟机所管理的内存将会包括以下几个运行时数据区。
程序计数器(Program Counter Register)
线程私有的一块较小的内存空间,当前线程所执行的字节码指令的行号指示器,字节码解释器工作时,就是通过改变这个指示器的值来选取下一条需要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复等基础功能就是依赖这个计数器来完成。
虚拟机栈(Java Virtual Machins Stacks)
Java方法执行的内存模型,线程私有,生命周期与线程一致,每个方法在执行时都会创建一个栈桢(Stack Frame),栈桢是方法运行时的基础数据结构,用于存放局部变量表,操作数栈,动态链接,方法出口等信息,每一个方法从调用到执行完成的过程就对应着一个栈桢在虚拟机中入栈和出栈的过程。
本地方法栈
本地方法栈和虚拟机栈所发挥的作用基本相同,区别在于虚拟机栈是为虚拟机执行的Java方法服务的,但是本地方法栈是为本地方法(Native)服务的,在虚拟机规范中没有明确规定对这本地方法栈使用的语言,使用方式和数据结构并没有强制规定,因此具体的虚拟机可以自由的实现它,与虚拟机栈一样,本地方法栈也会抛出OutOfMemoryException和StackObverFlowErr
堆(Heap)
所有线程共享,随线程的启动而创建,存放对象实例,是垃圾回收器管理的主要区域(GC堆),从内存回收角度考虑,可分为新生代,老年代,再细致一点可分为Eden控件,From Survivor控件,ToSurvivor空间,从内存分配的角度看,线程共享的JAVA堆可划分为多个线程私有的分配缓冲区。
方法区(Method Area)
所有线程共享,存放已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,Java虚拟机对这块的限制非常宽松,可以选择不实现垃圾回收,相对而言,垃圾收集行为在这个区域很少出现,这块区域的回收目的主要针对常量池的回收和对类型的卸载,这个区域的回收成绩很难令人满意,尤其是类型卸载,条件箱单苛刻,但是对这块区域的回收确实是有必要的。
运行是常量池
方法区的一部分,Class文件中除了有类的版本,方法,接口,字段等描述信息之外,还有一项信息是常量池,用以存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。
直接内存
并不是虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域,但是也被频繁使用,JDK1.4中加入NIO类,引入一种基于通道和缓存的I/O方式,通过使用Native函数直接分配对外内存,然后通过存储在Java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。这样能在一些场景显著提高性能,避免在Java堆和Native堆中来回复制数据????。