线程共享区域随虚拟机JVM的启动/关闭而创建/销毁。
Heap
(堆): 我们常说用于存放对象的区域,1.7之后字符串常量池移到这里。是被线程共享的一块内存区域,创建的对象和数组都保存在 Java 堆内存中,也是垃圾收集器进行垃圾收集的最重要的内存区域。
由于现代 VM 采用分代收集算法, 因此 Java 堆从 GC 的角度还可以细分为: 新生代(Eden 区、From Survivor 区和 To Survivor 区)和老年代。
Method Area
(方法区): 存储已被虚拟机加载的类信息、静态变量、编译后代码等数据。并使用永久代来实现方法区,1.8后被元空间替代,元空间并不在虚拟机中,而是使用本地内存。线程私有数据区域生命周期与线程相同, 依赖用户线程的启动/结束 而 创建/销毁。 在 Hotspot VM 内, 每个线程都与操作系统的本地线程直接映射, 因此这部分内存区域的存/否跟随本地线程的生/死对应。
VM Stack
(虚拟机栈): 方法执行时创建一个栈帧,用于存储局部变量、操作数栈、动态链接、方法出口等信息。每个方法一个栈帧,互不干扰。
Native Method Stack
(本地方法栈): 用于存放执行native方法的运行数据。 如果一个 VM 实现使用 C-linkage 模型来支持 Native 调用, 那么该栈将会是一个 C 栈,但 HotSpot VM 直接就把本地方法栈和虚拟机栈合二为一。
Program Counter Register
(PC, 程序计数器): 当前线程所执行的字节码的行号指示器
,通过改变计数器来选取下一条需要执行的字节码指令。 正在执行 java 方法的话,计数器记录的是虚拟机字节码指令的地址(当前指令的地址)。如果还是 Native 方法,则为空。 唯一一个在虚拟机中没有规定任何 OutOfMemoryError
情况的区域。
Direct Memory
(直接内存):
Class对象是存放在堆区的,不是方法区。 Class对象是加载的最终产品,类的元数据, 包括类的方法代码,变量名,方法名,访问权限,返回值等等才是存在方法区的。
class statics
)class statics
)移到了 堆(Heap
) 中 interned strings
)Hotspot 的 字面量(interned strings
) (或叫字符串常量池, 字符串池,字符串对象池,string pool
或 string literal pool
或 StringTable
) 在 Java 内存区域的哪个位置
Perm Generation
) 区 中,此时常量池中存储的是对象。
Heap
) 中了。此时常量池存储的就是引用了。在 JDK8.0 中,永久代 (Perm Generation
) 被 元空间 (Metaspace
)取代了。
上文翻译:
在JDK 7中,实例化的字符串不再分配在Java堆的永久代生成中,而是分配在Java堆的主要部分(称为年轻和老一代),以及另一个应用程序创建的对象。此更改将导致更多数据驻留在主Java堆中,并且永久生成中的数据更少,因此可能需要调整堆大小。由于此更改,大多数应用程序将只看到堆使用中相对较小的差异,但是加载许多类或大量使用该String.intern()方法的较大应用程序将看到更显着的差异。 - https://www.javatt.com/p/47643
by Sven Augustus https://my.oschina.net/langxSpirit