系统如何选择垃圾回收器
Posted 大Java
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了系统如何选择垃圾回收器相关的知识,希望对你有一定的参考价值。
在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% used;from space 21504K, 71% used;to 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% used;to 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)
也就是说,如果你购买的es服务,节点内存在32G内,只能使用cms垃圾回收器。我们也可以动手去看看其他java应用默认使用是什么垃圾回收器。比如hadoop,hbase,flink等这些优秀的大数据框架是怎么默认选择的。评论去来讨论你的发现吧
历史文章
以上是关于系统如何选择垃圾回收器的主要内容,如果未能解决你的问题,请参考以下文章
对“xxx”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。 错误解决一例。(代码片段