垃圾回收器选型
[原创]个人理解,请批判接受,有误请指正。转载请注明出处: https://heyfl.gitee.io/JVM/jvm-gc.html
总揽
吞吐量和最短停顿时间本来就互相矛盾
Parallel Old追求的是吞吐量,CMS追求的是STW的最短
而G1通过把堆分成多个相对独立的Region块,并行的进行选择性的回收,实现一个两者兼顾的回收器
Parallel GC:
适用于吞吐量优先的场景
- 原理: 通过参数-XX:GCTimeRatio 设置垃圾回收时间占总时间的比例,默认值为99,即垃圾回收时间不超过1%,实现吞吐量优先
CMS(Concurrent Mark Sweep)GC:
适用于响应时间优先的场景
- 原理1:通过-XX:CMSInitiatingOccupancyFraction预留空间实现一边回收垃圾,一边执行业务逻辑,实现响应时间优先
- 原理2:通过并发标记等,实现尽可能低的停顿
- 缺点1: 内存使用率低,为了一边干活一边回收垃圾,预留了一定的内存
- 缺点2:产生碎片,虽然FullGC时候,但是运行期间会产生大量碎片
(新增)G1(Garbage First)GC:
适用于大堆内存场景,通过Region分区,既实现超短GC暂停时间,同时保证吞吐量
原理1:通过Region分区+预测模型,优先回收垃圾最多的Region,实现可控制时间的超短GC暂停时间
原理2:使用复制算法,没有碎片
缺点1: 内存使用率低,因为新生代与老年代都用了复制算法,需要预留一定的内存
缺点2: GC效率低,每次都为不完全GC
缺点2: 默认内存使用45%开始FullGC
(新增)什么时候使用G1
- G1 的第一个重点是为运行需要大堆且 GC 延迟有限的应用程序的用户提供解决方案
- 非官方提示大约 6GB 或更大的堆大小,以及低于 0.5 秒的稳定且可预测的暂停时间选择G1
如果应用程序具有以下一个或多个特征,则现在使用 CMS 或 ParallelOldGC 垃圾收集器运行的应用程序将受益于切换到 G1。
- Full GC 持续时间太长或太频繁。
- 对象分配率或提升率差异很大
- 不需要的长时间垃圾收集或压缩暂停(超过 0.5 到 1 秒)
附录1.现有系统垃圾回收器选型
- admin(-Xmx8g -Xms8g)服务于前端,提供实时同步的http接口,注重高效响应,当前使用的是默认的Parallel GC,应该考虑使用
CMSG1回收器,并限制最大停顿时间<20 - Cache(-Xmx4g -Xms4g)不单独提供服务,主要负责数据消费与写入,注重吞吐量,当前使用的是CMS,不妥,应考虑使用Parallel GC
- Report(-Xmx5g -Xms5g),主要报表异步导出,注重吞吐量,当前使用的是G1,其实用Parallel GC可能也差不多
- Order:(Xmx4G -Xms4G),G1回收器,注重吞吐量,或许Parallel也是个很好的选择
- Operation:(Xmx12G -Xms12G) 想说G1回收器没跑了,目前也是用的这个,但作为数据消费者与生产者其实基本不怎么GC,其业务只注重吞吐量,其实或许Parallel也是个很好的选择,但这是个坑,因为这可能导致超长停顿,让与中间件等服务器之间的连接超时,出现故障