15 ZGC和shenandoah

好的问题

1.像 G1 和 ZGC 之类的现代 GC 算法,只要空闲的堆内存足够多,基本上不触发 FullGC。
所以很多时候,只要条件允许,加内存才是最有效的解决办法。
2.更小粒度的内存块划分,也就允许增量垃圾收集的实现,意味着暂停的时间更短。
3.优化停顿时间
(1)使用多线程“并行”清理堆内存,充分利用多核 CPU 的资源;
(2)使用“分阶段”的方式运行 GC 任务,把暂停时间打散;
(3)使用“增量”方式进行处理,每次 GC 只处理一部分堆内存(小堆块,region);
(4)让 GC 与业务线程“并发”执行,例如增加并发标记,并发清除等阶段,从而把暂停时间控制在非常短的范围内(目前来说还是必须使用少量的 STW 暂停,比如根对象的扫描,最终标记等阶段);
(5)完全不进行堆内存整理,比如 Golang 的 GC 就采用这种方式(题外话)。
4.内存整理,也就是重定位的过程是并发执行的,用到了我们前面说到的“读屏障”。
(1)需要把一个对象拷贝到另一个地址,这时另外一个线程可能会读取或者修改原来的这个老对象;
(2)即使拷贝成功,在堆中依然会有很多引用指向老的地址,那么就需要将这些引用更新为新地址
为了解决这些问题,ZGC 引入了两项关键技术:“着色指针”和“读屏障”。
着色指针是一种将信息存储在指针中的技术
ZGC 使用着色指针来标记所处的 GC 阶段。从这些标记上就可以知道对象目前的状态,判断是不是可以执行清理压缩之类的操作。
着色指针是从 64 位的指针中,挪用了几位出来标识表示 Marked0、Marked1、Remapped、Finalizable。所以不支持 32 位系统,也不支持指针压缩技术,堆内存的上限是 4TB。
空闲18位,标识位4位,地址位42位,2^42即4TB。

读屏障是JVM向应用代码插入一小段代码的技术。当应用线程从堆中读取对象引用时,就会执行这段代码。需要注意的是,仅“从堆中读取对象引用”才会触发这段代码。

5.如何达到高吞吐量的目的?多个线程并发执行就能高吞吐。
6. ZGC 把一部分 GC 工作,通过读屏障触发陷阱处理程序的方式,让业务线程也可以帮忙进行 GC。这样业务线程会有一点点工作量,但是不用等,延迟也被极大地降下来了
7.G1的Young GC和CMS的Young GC,其标记-复制全过程STW?

参考

https://tech.meituan.com/2020/08/06/new-zgc-practice-in-meituan.html
https://learn.lianglianglee.com/%e4%b8%93%e6%a0%8f/JVM%20%e6%a0%b8%e5%bf%83%e6%8a%80%e6%9c%af%2032%20%e8%ae%b2%ef%bc%88%e5%ae%8c%ef%bc%89/15%20Java11%20ZGC%20%e5%92%8c%20Java12%20Shenandoah%20%e4%bb%8b%e7%bb%8d%ef%bc%9a%e8%8b%9f%e6%97%a5%e6%96%b0%e3%80%81%e6%97%a5%e6%97%a5%e6%96%b0%e3%80%81%e5%8f%88%e6%97%a5%e6%96%b0.md

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值