1. JVM、HotSpot、 OpenJDK 的区别
- JVM (Java Virtual Machine) 是一个虚拟机
- HotSpot 是 JVM 规范的一个实现。HotSpot 虚拟机通过即时编译 (JIT) 技术将 Java 字节码转换为本地机器码,以提高程序的执行效率。
- OpenJDK 是一个项目名,它在 HotSpot 的基础上开发了 HotSpot 的开源实现
- JVM 中有一个规范叫方法区,而永久代(JDK 7)和元空间(JDK ≥ 8)是 HotSpot 的对方法区的具体实现 就如同 HotSpot 是 JVM 的实现 是一个道理
2. JVM 体系结构
- The pc Register(
程序计数器
):是一块较小的内存空间,此计数器记录的是正在执行的虚拟机字节码指令的地址; - Java Virtual Machine Stacks(
Java 虚拟机栈
):Java虚拟机栈用于存储栈帧。栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。 - Heap(
堆
):是Java虚拟机所管理的最大的一块内存。堆内存用于存放Java对象实例以及数组。堆是垃圾收集器收集垃圾的主要区域。 - Method Area(
方法区
):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 - Run-Time Constant Pool(
运行时常量池
):是方法区的一部分,用于存放编译期生成的各种字面量与符号引用。 - Native Method Stacks(
本地方法栈
):在本地方法的执行过程中,会使用到本地方法栈。和 Java 虚拟机栈十分相似。
3.0 HotSpot
3.1 JDK 6
- 年轻代:刚 new 出来的对象放在这里。
- 老年代:经过垃圾回收之后仍然存活的对象。
- 符号引用:类全名,字段全名,方法全名等。
- 这个时期的永久代和堆是相邻的,使用连续的物理内存,但是内存空间是隔离的。
- 永久代的垃圾收集是和老年代捆绑在一起的,因此无论谁满了,都会触发永久代
和老年代的垃圾收集。
3.1 JDK 7
- 类的静态变量转移到堆中了
- 字符串常量池转移到堆中了
- 运行时常量池中的符号引用转移到本地内存了
3.3 JDK 8
- 彻底删除永久代(为了避免 OOM 错误的发生)
- 将方法区的实现转移到本地内存
- 将符号引用重新放回运行时常量池