JVM垃圾收集算法与收集器

算法是什么?
复制算法copying:
新生代内:
GC ROOTS 根节点–>扫描M0老内存区–>标记live对象–>复制–>新内存M1–>清空M0老内存区
场景:live少, 为什么?反之 扫描+标记+复制+开辟新内存 增加成本
为什么放新生代?
答:新生代 eden from to 区域 内对象活动比较少 。
为什么效率高?
答:内存容量均等–>两块–>每次使用一块–>空间不够时–>触发复制算法进行回收–>删除老的内存块–>只对其中一块处理–>不考虑碎片问题
–>每次移动堆顶指针–>有序分配空间。
缺点是什么?
答:live多,复制成本高 效率低 || 内存缩小超过一半时,需要每次额外分配空间
注意:老年代不使用复制算法
G1收集器 在收集新生代时采用复制 在收集老年代时采用标记-整理 结合使用。
为什么老年代不使用复制算法?
答:因为live对象多,复制成本高 效率低。
标记清除算法mark-sweep:
答:
1. 标记 GC ROOTS根节点–>标记从根节点开始对象
2. 清除 GC ROOTS根节点–>检索未被标记的对象–>清除
优点是什么? 答:干掉–复制算法的内存减半
缺点是什么? 答:内存区域分散 出现内存碎片
标记整理算法mark-compact:
答:
1. 标记 GC ROOTS根节点–>标记从根节点开始对象
2. 整理 GC ROOTS根节点–>all live对象向一端移动【内存地址以此排序】–>清理掉边界【末端内存地址】外的内存。
优点是什么?
答: 干掉–复制算法的内存减半 重新分配内存代价
消除–内存碎片 也就是内存分散的缺点。
缺点是什么?
答:标记整理算法不适用老年代。
分代收集算法:
优点:
1.解决了标记整理不适用于老年代的问题
2.不同年代–不同算法
新生代–live少 复制
老年代–live多 标记-清除|| 标记整理
3.不对额外空间进行分配担保。
垃圾收集器的特点:
1. 是否串行?
2. 是否并行?
3. 是否支持并发?
4. 为哪个代提供服务?
5. 算法是什么?
6. 实现的目标是什么?
7. 使用场景是什么?

JVM垃圾收集器
新生代收集器
Serial 串行 新生代 复制算法 响应速度优先 单CPU环境下的Client模式
ParNew 并行 新生代 复制算法 响应速度优先 多CPU环境时在Server模式下与CMS配合
Parallel Scavenge 并行 新生代 复制算法 吞吐量优先 在后台运算而不需要太多交互的任务
老年代收集器
Serial Old 串行 老年代 标记-整理 响应速度优先 单CPU环境下的Client模式、CMS的后备预案
  Parallel Old 并行 老年代 标记-整理 吞吐量优先 在后台运算而不需要太多交互的任务
  CMS收集器 并发 老年代 标记-清除 响应速度优先 集中在互联网站或B/S系统服务端上的Java应用
新生代+老年代收集器
  G1 收集器
并发 新生代和老年代 标记-整理+复制算法 响应速度优先 面向服务端应用,将来替换CMS
  ZGC 收集器
   是一个可伸缩的、低延迟的垃圾收集器。

Serial收集器:
新生代串行 基于复制算法的垃圾收集器 快 但吞吐低
ParNew收集器:
新生代并行 基于复制算法的垃圾收集器 快 但吞吐低
Parallel Scavenge收集器:
新生代并行 基于复制算法的垃圾收集器 慢 但吞吐高

Serial Old收集器:
Serial收集器的老年代版本
老年代串行 基于标记整理算法的垃圾收集器 快 但吞吐低
Parallel Old收集器:
Parallel Scavenge收集器的老年代版本
老年代并行 基于标记整理算法的垃圾收集器 快 但吞吐低
CMS收集器:
基于标记-清除算法 获取最短回收停顿时间的垃圾收集器
过程:初始标记–>GC ROOTS关联到对象 0.1s
–>并发标记–>GC ROOT Tracing 1s
–>重新标记–>修正并发标记中改变的对象的标记记录 <1s
–>并发清除–>清除未标记对象。0.1s
举例:<2.2s
优点是什么?
答:并发收集 低停顿。 响应速度快。
缺点是什么?
答:并发标记时 占用线程 导致 吞吐量低
还是内存散落 处理不了浮动垃圾【线程运行中产生的 无法当次收集处理的 需下一次GC收集的】。
Concurrent Mode Failure(并发模式故障)–>导致FULL GC 产生。
为什么会触发FULL GC?
答:
内存碎片过多,大对象A无法分配空间–>老年代明明有空间确不连续–>A无法分配时会触发一次FULL GC。
G1收集器:
面向服务端应用,将来替换CMS
过程:初始标记–>并发标记–>最终标记–>筛选回收。
特点
1. 并行于并发:多核cpu 来缩短stop-The-World停顿时间。其他收集器需要停顿Java线程执行的GC动作,G1收集器并发让java程序继续执行。
2. 分代收集:独立管理GC堆–>保留分代–>处理创建和存活时间长的对象–>收集多次GC的老对象
3. 空间整合:与CMS的“标记–清理”算法不同, 整体:标记整理算法 局部:复制算法
4. 可预测的停顿:降低停顿时间–>建立预测停顿时间模型–>划分时间片段。

stop the world : jvm挂机 系统全局停顿现象。

ZGC垃圾收集器:
目标

  1. 停顿时间<=10ms
  2. 0-4T堆 停顿时间不变
  3. 128G堆-1.68ms SPECjbb 2015基准测试
    为什么可以这么快?
    答:只回收部分内存空间,避免了全堆扫描
    特点是什么?
    答:
    并发: 短暂STW,大部分过程均并发。减少并发标记和并发移动时间。
    空间划分:以page单位进行对象的分配和回收。去除了新生代和老年代概念。
    整理: page压缩 避免碎片化
    Numa织入:Numa架构插槽当服务 检索对象时 访问本地内存 拒绝访问另外CPU核上的内存区域 快。
    优先在从属内存区进行分配空间。
    使用标记指针:标记对象指针【<42bit用地址标记 42-45bit用指针标记】 区别于CMS G1对对象头标记
    使用读屏障:load barriers 确保GC线程和应用线程并发 标记和移动过程中 时 GC时数据读取正确
    变化:jdk11开始no uninstall–>jdk12优化 yes uninstall
    平台: Linux/x64
    调优
    设置堆最大内存: -Xmx10g
    设置并发执行GC线程数:-XX:ConcGCThread = 5 -cpu核数的12.5%
    如64核 8个GC线程 >8 则降低吞吐量 增加应用延迟。
    <4 则垃圾回收慢 造成应用线程停顿来释放内存。
    视情况而定最好。
    设置并行GC线程数:-XX:ParallelGCThreads = 20
    GC Roots进行标记和移动–>进行STW–>并行执行=->不影响应用线程执行。-cpu核数的60%
    为什么60%? 答:STW了,多一点线程 STW会更短。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值