本文共 1328 字,大约阅读时间需要 4 分钟。
Java垃圾回收机制深入分析
GC基础
在Java垃圾回收(GC)中,可达性分析是核心算法的基础。通过一系列GC Roots作为起始点,遍历对象图,找出无法从GC Roots到达的对象即可回收。
GC Roots
可以作为GC Roots的对象包括:
- 虚拟机栈中本地变量表中的引用的对象
- 本地方法栈中JNI引用的对象
- 方法区中类静态属性引用的对象
- 方法区中常量引用的对象
三色标记
三色标记法用于标记存活对象:
- white:未被标记
- gray:本身已标记,但部分引用的对象未被标记
- black:本身已标记,且所有引用的对象已被标记
标记过程从GC Roots出发,依次标记gray,再标记black。最终,white对象即为可回收对象。
分代收集
传统GC将堆分为三代:
- 年轻代:临时对象,快速回收
- 老年代:长期存活对象
- 永久代:类信息、字符串常量等
年轻代采用复制算法,老年代采用标记-清除或标记-整理。
标算法
Mark and Sweep
- 简单实现,GC停顿短
- 需维护空闲列表,内存碎片较多
Mark-Sweep-Compact
- 整理存活对象到连续空间
- 减少碎片,但复制对象导致停顿时间长
Mark and Copy
CMS回顾
CMS采用并发标记-清除算法,减少GC停顿。主要步骤:
初始标记:标记GC Roots直接可达的老年代对象 并发标记:标记存活对象,处理引用关系变化 预清理:处理并发修改导致的漏标 重新标记:扫描年轻代和老年代 并发清理:释放空闲空间 重置:清除数据结构,为下一轮GC准备 G1算法
G1(Garbage-First)是优化的服务器端GC,目标是先垃圾回收,减少停顿。主要特点:
- 并行运行,减少STW
- 整理空闲空间,减少碎片
- 提供可控的GC暂停时间
G1设计目的
- 适合多处理器大内存环境
- 取代CMS,提高吞吐量
- 采用增量回收,GC暂停时间可预测
G1基本概念
G1将堆划分为多个区域,新生代与老年代不连续,支持动态角色转换。每个区域细分为卡片,实现细粒度引用统计。G1通过动态调整CSet大小,优先回收垃圾多的区域,减少GC时间。
Young GC
初始堆只有YoungGen,触发YoungGC时将存活对象复制到另一个Survivor区域。G1通过多线程并行复制,减少停顿。
Concurrent Marking
G1并发标记包括:
初始标记(STW):标记GC Roots直接可达的老年代对象 Root Region Scan:扫描Root Region并标记可达对象 并发标记:线程遍历堆,标记存活对象 重新标记(STW):完成并发标记,处理引用更新 Mixed GC
Mixed GC处理CSet包含Old和Young区域的GC,基于RSet维护每个区域的引用关系。
RSet维护
RSet记录跨区域引用,维护:
- 应用线程写操作触发写后屏障
- 异步更新RSet,减少写屏障开销
总结
并发标记与增量收集是G1高性能与可预测GC的关键。G1适合CPU资源充足且对延迟敏感的服务端应用,提供良好响应速度。然而,额外的写屏障和活跃GC线程会影响吞吐量,需权衡GC性能与应用性能。
转载地址:http://cfxkz.baihongyu.com/