前言
JVM
虚拟机,是每个 Java 程序员都绕不过去的坎儿。
本篇一起来学习下,JVM
内存区域的划分以及各部分的作用。
本篇中,大部分资料来源于 周志明 《深入理解 Java 虚拟机 第三版》,以及网络资料。
JVM
内存区域
JVM
内存区域划分大致如下:
从线程的角度看,可分为两大区域,线程共享区域和线程私有区域。
-
线程共享区域
JVM
内所有线程,都可访问到的区域。- 方法区
- 堆
-
线程私有区域
只有本线程,才可访问到的区域。
- 虚拟机栈
- 本地方法栈
- 程序计数器
程序计数器
用于记录代码当前的执行位置。
当前执行 Java 方法时,记录当前正在执行的虚拟机字节码指令地址。
当前执行 Native方法时,不记录值。
由于JVM
多线程是通过线程轮流切换、分配CPU执行时间的方式实现的。
所以每个线程都需要一个程序计数器,用于记录代码的执行位置,以待下次切换回来时,能够恢复到正确的执行位置。
虚拟机栈
虚拟机栈的大致结构如下:
方法被调用时,JVM 便创建一个栈帧(Stack Frame),用于保存局部变量表,操作数栈,动态链接,方法出口等信息。
方法调用时,入栈;方法完毕时,出栈。
本地方法栈
与虚拟机栈功能一致。保存 Native 方法。
HotSpot 虚拟机中,虚拟机栈与本地方法栈合二为一。
堆
堆的唯一目的就是存放对象实例。
Java 中“几乎”所有对象,都存放在堆中。之所以用“几乎”,是因为随着栈上分配、标量替换等优化手段的出现。
逃逸分析利用标量替换实现堆上的对象分解为栈上的标量。
堆是垃圾回收的重点区域。
堆的分区
大致如下:
-
新生代
新生代占据堆的三分之一。但是因为新生代中分区较多,所以图例有些失衡,需要注意。
- Eden 区
- Survivor 区
-
老年代
对象的分配流程
这里使用一张图,来简单描述一下 Java 对象的配置过程。
图中,我们可以看到分配对象一共有四个大阶段:
-
逃逸分析。
满足逃逸条件的,可直接在栈上分配。
-
是否为大对象。
大对象直接进入老年代。 如果老年代内存不足,进行一次
Full GC
,一次Full GC
之后,还内存不足,直接OOM
-
是否满足
TLAB
分配。例如一些对象不涉及多线程竞争的,就可优先在堆的线程私有区域进行分配。
-
年轻代 - Eden 区划分。
上述条件都不满足时,最终会将对象分配至
Eden
区。Eden
区内存不足时,发起一次Young GC
,之后内存还不足时,抛出OOM
。
这里我们简单的了解一下,对象分配的过程。其中还有许多知识点,不是一次就能搞清楚的,例如 逃逸分析后的优化手段、分配担保机制等等。
我们后续再继续学习这些比较深入的知识点。
常用命令
- -Xms: 初始堆空间内存 (默认为物理内存的1/64)
- -Xmx: 最大堆空间内存(默认为物理内存的1/4)
- -XX:NewRatio: 配置新生代与老年代在堆结构的占比(默认2)
- -XX:SurvivorRatio :设置新生代中Eden区与Survivor区的比例。(默认值8)
- -XX:UseTLAB:设置是否开启TLAB空间。(默认打开)
- -XX:TLABWasteTargetPercent:设置TLAB空间所占用Eden空间的百分比大小。
- -XX:MaxTenuringThreshold=N次 年龄晋升老年代阈值(包含)
方法区
用于存储已被 JVM 加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。这是堆的一个逻辑部分。
《Java虛拟机规范》中明确说明:“尽管所有的方法区在逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩。”但对于 HotSpot JVM 而言,方法区还有一个别名叫做Non-Heap (非堆),目的就是要和堆分开。所以,方法区看作是一块独立于Java堆的内存空间。
也就是说,在不同的 JVM 虚拟机中,方法区的实现方式可能是不一样的。
实际上,在 Hot Spot JVM 中,不同版本之间方法区的实现方式也是不一样的。
在 JDK 8 以前,Hot Spot 用永久代来实现方法区;而在 JDK 8 及之后,已经改为在本地内存中的实现的元空间 ( Meta-space) 来代替。
版本区别
版本 | 变化 |
---|---|
JDK 1.6及之前 | 有永久代(permanent generation)。永久代行使方法区的功能。 |
JDK 1.7 | 有永久代,但已经逐步“去永久代”。字符串常量池、静态变量移至堆中。 |
JDK 1.8及之后 | 无永久代,类型信息等移至元空间中,字符串常量池、静态变量仍在堆。 |
命令
-
-XX:MetaspaceSize
设置元空间初始化空间
-
-XX:MaxMetaspaceSize
设置元空间内存最大空间