不少java程序员一提JVM运行时数据区域,就会说堆和栈,当然也有java程序员给出方法区、虚拟机栈、本地方法栈、堆、程序计数器这个答案,但是还有人给出永久代、虚拟机栈、本地方法栈、堆、程序计数器这个答案。那么究竟哪种答案是正确的呢?
首先我们介绍两个概念,这对于我们回答上面的问题来说是必不可少的。 1.虚拟机: 简单的说虚拟机是一种抽象的计算机。 2.Java虚拟机规范: 虚拟机规范是一种对Java虚拟机的约束,Java虚拟机负责对虚拟机规范进行实现。 我们平常所说JAVA虚拟机一般是指的一种具体的JAVA虚拟机规范的实现,比如说HotSpot。当然市面上还有其他的Java虚拟机。 下面的截图内容来自docs.oracle.com/javase/spec…
从JVM6规范,我们可以看到,规范要求的运行时数据区域有: PC Register(程序计数器)、Java Virtual Machine Stacks(java 虚拟机栈)、Heap(堆)、Method Area(方法区)、Native Method Stacks(本地方法栈)、Runtime Constant Pool(运行时常量池这及部分)。 注意标红部分,我们可以看到运行时常量池位于方法区内。 根据规范我们可以大概的画出JVM运行实数据区域(执行引擎、本地库接口在后面的文章中会进行详细介绍)。




请看下一张图。 jdk版本在1.8。MetaSpace是什么鬼?
Jdk1.8移除了永久代或者说用MetaSpace去实现虚拟机规范中的方法区。 详见:JEP 122: Remove the Permanent Generation 我查了很多资料,还是没有找到官方对MetaSpace的解释和描述,到是在深入探究 JVM | 探秘 Metaspace这篇博客中看到了MetaSpace的相关描述。 In JDK 8, classes metadata is now stored in the native heap and this space is called Metaspace.
字符串常量池仍然在堆中,方法区移动至MetaSpace中 那么如果有人问你JVM运行时区域由几部分组成,那么应该如何回答呢? 我认为答案可以是这样的:JVM规范中的要求JVM运行时区域有以下及部分:
1、 方法区
2、 java虚拟机栈
3、 本地方法栈
4、 堆
5、 程序计数器
6、 运行时常量池(位于方法区中) 但是不同的虚拟机对规范有着不同的实现,HotSpot1.6对方法区的实现叫永久代,1.7将字符串常量池移动到了堆中,1.8移除了永久代改用元数据区实现方法区,字符串常量池仍然在堆中。


