vlambda博客
学习文章列表

系统如何选择垃圾回收器

   

在hotspot虚拟机内,常见的垃圾回收器上篇文章已经列举过了()。

那在我们的系统内如何选择一个合适的垃圾收集呢这是需要时间才能出结果的,一口气给你一个答案的人那大概率是拍脑袋想的。

        

系统如何选择垃圾回收器

从理论的角度讲,如果服务器的一个jar程序分配的最大内存不超过6G,CMS使用标记-清除算法性能比较好,如果一个jar程序分配的内存在16G甚至更多的时候,jdk升级到jdk7及以上可以选用G1,G1使用的是Mixed GC模式标记-整理算法。这两种选择的目的都是希望让我们的服务停顿时间更短,这类应用一般是偏向用接口应用,用户需要快速看到操作结果,如果说是数据跑批系统,数据分析系统,我们关心的是整体的吞吐量,如果让系统的可运行生命周期更宽。假如说现在有一个系统,里面没有提供web应用接口,全是定时任务,处理统计数据,那对于Parallel Scavenge收集器是不建议去选择的,CMS会让内存空间出现大量的碎片空间,如果我们使用G1收集器需要注意的是什么?跑批程序的特点就是 ,分页查询数据,内存比较,修改,遍历等等,分页页码有的是两千,有的是五千,那这些对象都会有可能成为大对象,直接放进Humongous区域。索性直接使用ParNew收集器。你感觉会有什么问题?

上面说的都是理论建议,实战中一定不能纸上谈兵,只有根据实际情况去测试才是选择收集器的最有效依据。

在linux服务器上面常用的设置参数如下:

系统如何选择垃圾回收器该图引自《深入理解JAVA虚拟机》

有一系列参数也许你会用上

-XX:+PrintGC #打印gc基本信息-XX:+PrintHeapAtGC #每次gc后都会打印堆上的信息-XX:+PrintGCApplicationStoppedTime #记录每次GC后系统的停顿时间-XX:+PrintGCApplicationConcurrentTime #记录GC后所有线程停顿的时间

 在启动程序内,如果设置这些参数,会在日志内看到对应的gc日志例如下。

  

系统如何选择垃圾回收器

系统如何选择垃圾回收器第一张图看到的信息是第七次GC前的内存情况是

  • PSYoungGen total 246784K, used 15440K(eden space 225280K, 0% usedfrom space 21504K, 71% usedto   space 22528K, 0% used)

  • ParOldGen total 167424K, used 5745K(object space 167424K, 3% used)

  • Metaspace used 33988K, capacity 35356K, committed 35496K, reserved 1079296K(class space    used 4516K, capacity 4756K, committed 4864K, reserved 1048576K)


GC后的内存情况是

  • PSYoungGen total 246784K, used 0K(eden space 225280K, 0% used;from space 21504K, 0% usedto   space 22528K, 0% used)

  • ParOldGen total 235008K, used 19953K(object space 167424K, 8% used)

  • Metaspace used 33988K, capacity 35356K, committed 35496K, reserved 1079296K(class space    used 4516K, capacity 4756K, committed 4864K, reserved 1048576K)


此次GC执行效果是对young空间进行了清理,但是old总空间变大了,使用率也比gc前增高了。元空间大小没有发生变化。
第二张图的信息就是说每次GC后系统的停顿时间,我们可以通过日志服务计算出整个程序的吞吐量,来衡量你的垃圾回收器是否服务业务场景。

最后举一个小场景,也是我在阿里云使用elasticsearch服务的时候发现的阿里云对es的垃圾回收器的一个配置。

系统如何选择垃圾回收器

也就是说,如果你购买的es服务,节点内存在32G内,只能使用cms垃圾回收器。我们也可以动手去看看其他java应用默认使用是什么垃圾回收器。比如hadoop,hbase,flink等这些优秀的大数据框架是怎么默认选择的。评论去来讨论你的发现吧


 历史文章