作者
Yuchao_Huang
来源
urlify.cn/AVzIra
引言网上有大量讨论JVM的内存模型的文章,但很多内容都是到处摘抄而来,导致许多概念模糊不清。
比如对于“JVM内存模型”和“Java内存模型(JMM)”没有区分,实际上,Java内存模型(JMM)是一种规范,和具体的Java虚拟机的内存结构不是一个概念,不应该把诸如“年轻代“、”老年代”这类关于虚拟机具体实现的讨论归为Java内存模型。
而在具体讨论JVM的内存结构时,还应该指出,我们通常讨论的都是HotSpot虚拟机中的实现,这些模型并不是所有虚拟机通用的,比如“PermGen(永久代)”就是HotSpot中的概念,JRockit中并没有永久代。
此外,不应该把“永久代”和“方法区”混为一谈,永久代(PermGen)只是HotSpot对于Java虚拟机规范中方法区(MethodArea)的一种实现,后来被改成了元空间(MetaSpace),文中会具体介绍这些变化。
本文希望从Java虚拟机规范出发,尽可能通过查阅官方文档,以及阅读HotSpotVM中的部分核心源代码的方式,重新梳理Java虚拟机的内存结构,重点讨论:
HotSpot虚拟机中,Heap(堆),MethodArea(方法区)和Run-TimeConstantPool(运行时常量池)的关系
MethodArea的在JDK1.6,JDK1.7和JDK1.8中的变迁(PermGen的消失和MetaSpace的出现)
字符串常量池的转移以及运行时常量池和intern方法的变化等。
而Jvm中的ThepcRegister、JavaVirtualMachineStacks和NativeMethodStacks这些部分,则不在本文的讨论范围之内。
Java虚拟机规范中的内存模型Java虚拟机规范上指定了Java虚拟机的运行时数据区包括ThepcRegister、JavaVirtualMachineStacks、Heap、MethodArea、Run-TimeConstantPool和NativeMethodStacks这些部分,其中PC寄存器,Java虚拟机栈和本地方法栈会为每个线程所创建,属于线程私有,而堆,方法区和运行时常量池是所有线程共享的。
PC寄存器,Java虚拟机栈和本地方法栈的作用与传统的操作系统类似,这里不多赘述,我们主要