1 运行时数据区
JVM运行时数据区是Java虚拟机管理的内存核心模块,主要分为线程共享和线程私有两部分。
(1)线程私有
① 程序计数器:存储当前线程执行字节码指令的地址,用于分支、循环、异常处理等流程控制
② 虚拟机栈:存储方法调用的栈帧,包含局部变量表、操作数栈、动态链接、方法返回地址等
③ 本地方法栈:服务于Native方法(如C/C++实现的方法)的执行,结构与虚拟机栈类似
(2)线程共享
① 堆:存储对象实例和数组,是垃圾回收(GC)的主要区域
② 方法区:存储类元信息(如类名、字段、方法)、运行时常量池、静态变量、即时编译后的代码等(JDK 8及之后:元空间(MetaSpace),使用本地内存)
2 三大GC算法
2.1 标记-复制算法(年轻代)
原理:将内存分为两块(如Eden区和Survivor区),每次仅使用一块;存活对象复制到未使用的内存块,原内存块整体回收
优点:无内存碎片,对象分配效率高
缺点:需要一块内存;复制对象过程比较耗时
2.2 标记-清除算法
原理:从GC Roots出发,标记所有可达对象(标记);回收未被标记的对象即垃圾(清除)
优点:实现简单,无需移动对象
缺点:有内存碎片问题,可能导致后续大对象分配失败
2.3 标记-整理算法
原理:从GC Roots出发,标记所有可达对象(标记);将存活对象向内存一端移动,清理边界外的空间(整理)
优点:避免内存碎片,支持连续内存分配
缺点:整理过程需STW;复制对象过程比较耗时
无论什么GC回收算法,第一阶段都是标记,根据根可达性分析,从GC Roots出发开始遍历访问,找出有效对象。
2.4 标记算法—三色标记法
三色
① 白色:尚未遍历过
② 黑色:本对象已经遍历过,而且本对象引用的其他对象也全部遍历过
③ 灰色:本对象已经遍历过,而且本对象引用的其他对象尚未全部遍历完
基本流程
① 初始阶段:所有对象都在【白色集合】中
② 将GC Roots直接引用的对象挪到【灰色集合】中,并将其从【白色集合】中去掉
③ 从【灰色集合】中获取对象,将本对象引用的其他对象全部挪到【灰色集合】中,并从【白色集合】中去掉,将本对象挪到黑色集合中
④ 重复 步骤③ 操作,直至【灰色集合】为空时结束
⑤ 结束后,仍在【白色集合】中的对象就是垃圾,可以回收
说明:图片引用自 https://zhuanlan.zhihu.com/p/664929804?utm_id=0
3 常见垃圾收集器
3.1 新生代(标记-复制算法)
Serial New:单线程收集器
ParNew:并行收集器(Serial多线程版本)
Parallel Scavenge:并行回收,追求高吞吐量,高效利用CPU
3.2 老年代
Serial Old:单线程收集器(标记-整理算法)
Parallel Old:并行收集器(标记-整理算法)
CMS:以低停顿为目标,分阶段并发执行<初始标记、并发标记、重新标记、并发清除>(标记-整理算法)
(1)步骤:
① 初始标记:SWT,仅标记GC Roots能直接关联的对象,速度比较快
② 并发标记:可以和用户线程并发执行,通过GC Roots可达性算法标记所有可达对象
③ 重新标记:STW,对并发标记阶段产生的垃圾对象进行标记修正,以及更新逃逸对象
④ 并发清除:可以和用户线程并发执行,清除可回收对象
(2)优点:支持并发收集,低停顿,能保证短时间内执行完成,达到近似并发目的
(3)缺点:
① 无法清理浮动对象
② 使用标记-清除算法,会产生大量内存碎片
③ 必须要在老年代用尽之前完成垃圾回收,否则会触发担保机制,退化成Serial Old收集器来进行垃圾回收,效率低下
(4)使用场景:老年代垃圾回收,需低停顿的交互式应用;堆内存不宜过大(避免并发标记耗时过长)
(5)配置参数
-XX:+UseConcMarkSweepGC:启用CMS收集器
-XX:CMSInitiatingOccupancyFraction:设置触发CMS回收的老年代使用率阈值(默认92%)
-XX:+CMSParallelRemarkEnabled:启用并行重新标记(减少重新标记时间)
3.3 不分代
G1:将堆划分为多个大小相等的Region,采用标记-整理算法(全局)和标记-复制算法(局部)
(1)原理:分治法,将堆分成若干个等大的区域Region(默认2048个,每个1-32MB)
(2)优点: 低停顿;基于标记-整理算法无内存碎片;大堆友好,支持TB级堆内存
(3)缺点:
① 内存占用:维护RSet(记忆集)和CSet(回收集)需额外内存
② CPU消耗:并发标记和RSet更新增加CPU开销
③ 复杂调优:需平衡停顿时间、吞吐量和Region大小等参数
(4)使用场景:大内存服务端应用;低延迟需求;JDK 9+默认收集器
(5)配置参数
-XX:+UseG1GC:启用G1收集器
-XX:MaxGCPauseMillis:设置最大GC停顿时间目标(默认200ms)
-XX:G1HeapRegionSize:指定Region大小(需为2的幂)
-XX:G1MixedGCLiveThresholdPercent:设置混合GC中Region存活对象占比阈值(默认85%,高于此值不回收)
ZGC:基于并发标记-整理算法,使用染色指针和读屏障技术,实现亚毫秒级停顿(支持TB级堆内存管理)
4 JDK各版本默认使用垃圾收集器
≤1.5 Serial + Serial Old
1.8 Parallel Scavenge+ Parallel Old
9~21 G1
11/17/21 新增ZGC/Shenandoah/Epsilon
通过命令行查看当前JDK默认垃圾收集器
java -XX:+PrintCommandLineFlags -version