本文共 4355 字,大约阅读时间需要 14 分钟。
转:
网上有大量讨论JVM的内存模型的文章,但很多内容都是到处摘抄而来,导致许多概念模糊不清。
比如对于“JVM内存模型”和“Java内存模型(JMM)”没有区分,实际上,Java内存模型(JMM)是一种规范,和具体的Java虚拟机的内存结构不是一个概念,不应该把诸如“年轻代“、”老年代”这类关于虚拟机具体实现的讨论归为Java内存模型。
而在具体讨论JVM的内存结构时,还应该指出,我们通常讨论的都是HotSpot虚拟机中的实现,这些模型并不是所有虚拟机通用的,比如“Perm Gen(永久代)”就是HotSpot中的概念,JRockit中并没有永久代。
此外,不应该把“永久代”和“方法区”混为一谈,永久代(Perm Gen)只是HotSpot对于Java虚拟机规范中方法区(Method Area)的一种实现,后来被改成了元空间(MetaSpace),文中会具体介绍这些变化。
本文希望从Java虚拟机规范出发,尽可能通过查阅官方文档,以及阅读HotSpot VM中的部分核心源代码的方式,重新梳理Java虚拟机的内存结构,重点讨论:
而Jvm中的The pc Register
、Java Virtual Machine Stacks
和Native Method Stacks
这些部分,则不在本文的讨论范围之内。
Java虚拟机规范上指定了Java虚拟机的运行时数据区包括The pc
Register、Java Virtual Machine Stacks、 Heap、 Method Area、Run-Time Constant Pool和Native Method Stacks这些部分,其中PC寄存器,Java虚拟机栈和本地方法栈会为每个线程所创建,属于线程私有,而堆,方法区和运行时常量池是所有线程共享的。
PC寄存器,Java虚拟机栈和本地方法栈的作用与传统的操作系统类似,这里不多赘述,我们主要关注Heap(堆),Method Area(方法区)和Run-Time Constant Pool(运行时常量池)的规范。
首先查看Java虚拟机中对Heap的定义:
The Java Virtual Machine has a heap that is shared among all Java Virtual Machine threads. The heap is the run-time data area from which memory for all class instances and arrays is allocated.
上面的定义指出,Heap是Java虚拟机中为所有Java虚拟机线程所共享的内存区域,它是一块为所有对象和数组分配内存的运行时数据区。
规范中还有下面的一段描述:
The heap is created on virtual machine start-up. Heap storage for objects is reclaimed by an automatic storage management system (known as a garbage collector); objects are never explicitly deallocated. The Java Virtual Machine assumes no particular type of automatic storage management system, and the storage management technique may be chosen according to the implementor's system requirements. The heap may be of a fixed size or may be expanded as required by the computation and may be contracted if a larger heap becomes unnecessary. The memory for the heap does not need to be contiguous.
文字有点长,不过我们可以总结出几个有关Heap的要点:
看完Java虚拟机规范中对Heap的描述,我们最需要记住的一点是:Heap是一块为所有对象和数组分配内存的运行时数据区
首先看Java虚拟机规范中对Method Area的定义:
The Java Virtual Machine has a method area that is shared among all Java Virtual Machine threads. The method area is analogous to the storage area for compiled code of a conventional language or analogous to the "text" segment in an operating system process. It stores per-class structures such as the run-time constant pool, field and method data, and the code for methods and constructors, including the special methods (§2.9) used in class and instance initialization and interface initialization
上面一段文字的含义是,Method Area(方法区)是Java虚拟机中为所有Java虚拟机线程所共享的内存区域,它类似于传统语言中存储编译后代码的区域,或者可以说它类似于操作系统进程中的'text'段(代码段,在操作系统中内存会分为数据段,代码段,堆,栈和BBS段)。
Method Area用于保存每个类的结构信息,如运行时常量池、字段和方法数据、以及方法和构造器的代码,包括用于类,对象和接口初始化的特殊方法。
下面还有一段描述,看起来跟对Heap的描述很像:
The method area is created on virtual machine start-up. Although the method area is logically part of the heap, simple implementations may choose not to either garbage collect or compact it. This specification does not mandate the location of the method area or the policies used to manage compiled code. The method area may be of a fixed size or may be expanded as required by the computation and may be contracted if a larger method area becomes unnecessary. The memory for the method area does not need to be contiguous.
上面的文字有以下要点:
从Java虚拟机规范的描述可以看出,规范对Method Area的定义是比较宽泛,只是定义了一块内存区域,用于存储类的结构信息。它没有严格定义Method Area在内存中的位置,也没有规定对它进行垃圾回收等管理策略。
因此,我们不应该认为Method Area和Heap是完全割裂的两块内存区域,它甚至可以是Heap的一部分。
老样子,先看定义:
A run-time constant pool is a per-class or per-interface run-time representation of the
constant_pool
table in aclass
file (§4.4). It contains several kinds of constants, ranging from numeric literals known at compile-time to method and field references that must be resolved at run-time. The run-time constant pool serves a function si.........
本文转载自:http://www.shaoqun.com/a/648731.html
转: