Skip to main content

关于JVM内存泄漏之GC优化问题提出

Submitted by taotao on Fri, 06/28/2019 - 12:14

概述

根据上一篇文章,将JVM升级到212版本,并追加设置了-Xmx和-Xms参数之后,生产环境的JVM内存一直维持在300-800M之间,高负载和低负载的实例,内存开销都在这个范围之内。所以从这两天的线上验证的现象来看是符合预期的,证实了之前的猜测是正确的(之前的结论参考:JVM的内存泄漏调查)。

详细分析

下面我将结合听云监控上的数据进行分析和论证。

下图是内存开销,可以看出内存开销在500M范围以下。

tingyun_memory_size

下面是Eden区域的内存开销,可以看出eden区大小在250M之内。

tingyun_eden_size

再来看看GC的运行的情况,这里看出来GC运行的频次明显比之前的(参考我之前的文章:JVM的内存泄漏调查) 要提高很多。

tingyun_gc

综合如上的监控数据,可以得出如下的结论

1、因为升级了JVM到 212版本,并且设置了JVM的-Xmx参数,使得JVM的内存增长不再以物理机器的内存作为依据,而是以docker容器本身的内存大小作为增长的依据。

2、GC的回收频次也比以前要提高很多,这说明当JVM自动扩容之后,如果没有达到GC的条件,就不会触发GC执行的,因此如果当前的JVM版本不能正确识别出docker的内存大小,就会导致JVM持续增长到物理机器内存的1/4,直到达到docker的内存限制极限,就会导致docker的内存溢出。

总结和新问题的发现

当前问题中我们可以通过提高JVM版本使之兼容 docker,设置Xmx参数的方式来让JVM识别出正确的内存大小。但是在关于GC的图中,我们可以看到GC在15分钟内执行了134次,每次GC耗时在15-20ms左右,如果一个接口需要100ms内返回数据,如此高频次的GC必然会对服务的吞吐率带来不利的影响。因此我们需要继续研究如何降低GC的频次。

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.