Java中的GC
2022-09-09 本文已影响0人
侧耳倾听y
判断对象死亡
- 引用计数法
- 可达性分析算法
GC 算法
标记清除
- 缺点:空间碎片
复制
- 缺点:只能使用一半的内存,代价大
标记整理
分代
- 前提:大部分对象朝生夕死,存活较长时间的对象,可能会存活更久
- 年轻代使用复制算法;老年代使用标记清除算法
- 对象优先在eden分配;大对象直接进入老年代;长期存活的对象进入老年代;动态对象年龄判定;空间分配担保
GC 实现
串行
- serial
年轻代收集器 - serial old
年老代收集器 - 总结
serial和serial old搭配使用,适合单cpu小内存(几百兆)的机器,默认client场景下的收集器
并行
- parNew
serial的多线程版本,除了serial外,能和CMS搭配使用的收集器 - parallel
吞吐量优先的垃圾收集器,可以调节吞吐量和停顿时间;有自适应策略;适合后台运算不需要太多交互的程序
并发
CMS
步骤:
- 初始标记:标记gc roots,会stw
- 并发标记:gc roots tracing
- 并发预清理:标记脏区
- 最终标记:完成所有存活对象的标记,会stw
- 并发清除:删除不再使用的对象
- 并发重置
优点:降低多核CPU的GC停顿导致的系统延迟
缺点:
- 无法处理浮动垃圾,默认68的时候触发垃圾回收,如果concurrent mode failure会使用serial old收集器导致停顿时间很长
- 会产生空间碎片
- CPU资源敏感,总吞吐降低
G1
- CMS的升级版
- 整个内存区划分为2048个堆区域,每个区域是eden或是s或是old是动态变化的
- 增量垃圾回收,每次处理一部分。垃圾最多的小块会被优先收集
- 将STW停顿时间和分布变成可预期的
- 某些fullgc情况退化到serial,STW时间到秒级别:
并发模式失败
晋升失败
巨型对象分配失败
GC 如何选择
- 吞吐量优先,CPU资源最大程度处理业务,使用parallel gc
- 低延迟优先,使用CMS
- 系统内存较大(4g以上),同时希望GC时间可控,使用G1