当前位置:首页 » JAVA技术教程

JVM运行时数据区域

2014-10-16 21:18 本站整理 浏览(9)
1.根据JVM规范,JVM运行时数据区域分为两部分:
1.1基于JVM的,这类数据区域在JVM启动时创建,JVM退出时销毁。
1.2.基于线程的,这类数据区域在线程创建时创建,线程退出时销毁。
2.JVM规范中定义了6中运行时数据区域(参考:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5),分别为:
2.1pc Register(程序计数器寄存器)
2.2JVM Stacks(JVM栈,在JVM规范1中叫做java栈)
2.3Heap(堆)
2.4Method Areas(方法区)
2.5Run-Time Constant Pool(运行时常量池)
2.6Native Method Stacks(本地方法栈)
根据JVM的规范解释和1的分类规则,运行时数据区域划分如表如下:
JVM启动时创建,JVM退出时销毁
线程创建时创建,线程退出时销毁
线程共有
Heap(堆)
Method Area(方法区)
Run-Time Constant Pool(运行时常量池)
线程私有
JVM Stacks(JVM栈)
Native Method Stacks(本地方法栈)
pc Register(程序计数器寄存器)
图:


虚线表示逻辑划分。
例如Method Area只是在逻辑上属于Heap,所以用虚线表示,因为JVM并没有规定Method Areas的物理内存必须来源于Heap,而仅仅是逻辑上的归属关系。
pc Register:
JVM支持同时运行多个线程(就是支持多线程)。每个JVM线程拥有自己的pc register(程序计数器寄存器)。任何一个时刻JVM线程都只执行一个方法代码,即这个线程的当前方法。
如果这个方法不是native方法,pc register包含JVM正在执行指令的地址。如果这个方法是native方法,JVM pc register的值是undefined。JVM pc register的宽度足以容纳一个返回地址或者一个特殊平台的原生指针。
JVM栈:
每个JVM线程拥有自己私有的JVM栈,当线程创建的时候JVM栈被创建。JVM栈存储帧 (§2.6)。JVM栈类似于常规语言的栈,如C:栈拥有本地变量和部分结果,方法调用和返回的一部分。由于JVM栈除了push和pop帧不能被直接操作,帧可能是从heap(堆)分配来的。JVM栈内存不要连续。
在Java虚拟机规范第一版中,Java虚拟机堆被称为Java栈。
JVM规范允许JVM栈是固定大小的或者是根据需要计算扩展和收缩的。如果JVM栈是固定大小的,每个JVM栈的大小可能是在栈被创建的时候独立选定的。
JVM实现可能提供给程序员或者用户控制覆盖JVM栈的初始大小,比如,动态扩展或者收缩JVM栈的情况,可以控制覆盖栈的最大和最小大小。
Heap:
JVM拥有一个被所有JVM线程共享的堆。堆是一块运行时数据区域,这块内存为类实例和数组分配空间。
堆是在虚拟机启动时创建的。堆中存储的对象是被自动存储管理系统(成为垃圾回收期)回收的;对象永远不会显示的释放。JVM不采取特定类型的存储管理系统,并且存储管理技术可以根据具体实现系统的需求选择。堆可以是规定大小的,也可以根据需要计算扩展,如果不予要一个更大的堆也可以收缩。堆内存不要连续。
JVM实现可能提供给程序员或者用户控制覆盖堆的初始大小,比如,堆可以动态扩展或者收缩,可以控制覆盖堆的最大和最小大小。
Method Area:
JVM拥有一个被所有JVm线程共享的方法区。方法区类似于一种常规语言存储编译完成的代码的区域,或者说类似于操作系统中的“文本”段。方法区存储每个类的结构,比如运行时常量池,域,方法数据,方法和构造方法的代码,包括在类和实例初始化以及接口初始化中使用的特殊的方法。
方法区是在JVM启动时创建的。虽然方法区逻辑上是属于堆的,简单的实现可能选择不对方法区垃圾回收或者压缩。此版本的Java虚拟机规范并不强制方法区的位置,也不强制用于管理已编译代码的策略。方法区也是可以扩展和收缩的。方法区不要求连续。
Run-Time Constant Pool:
运行时常量池是类文件中的constant_pool表在每个类和接口运行时的表示。它包含多种类型的常量,范围从编译期的数字文本到必须在运行期处理的方法和域的引用。运行时常量池提供类似于一个传统的编程语言中的符号表的功能,但它包含了比典型的符号表范围更广的数据。
每个运行时常量池都是从JVM方法区分配的。当JVM创建类和接口时,类和接口的运行时常量池将被创建。
Native Method Stacks:
一个JVM实现可能使用传统栈,通俗的称之为“C栈”,用以支持native方法(用其他语言写的方法而不是Java语言)。某种语言(比如C语言)针对JVM指令集的解释器实现也可以使用本地方法栈。(注:简单的说,就是其他语言可以使用本地方法栈)JVM实现不能加载native方法,不依赖于传统栈的JVM实现也不需要支持本地方法栈。如果JVM实现支持本地方法栈,当线程创建时JVM实现为每个线程分配本地方法栈。
JVM规范允许本地方法栈是固定大小的或者是根据需要计算扩展和收缩的。如果本地方法栈是固定大小的,栈的大小可能是在被创建的时候独立选定的。