4

我们目前遇到了 java 本机内存泄漏的问题。服务器相当大(40cpus,128GB 内存)。Java 堆大小为 64G,我们运行一个非常占用内存的应用程序,使用大约 400 个线程将大量数据读取到字符串中,并在几分钟后将它们从内存中丢弃。

所以堆很快就被填满了,但是堆上的东西已经过时了,也可以很快被 GC 处理。所以我们必须使用 G1 来避免 STW 休息几分钟。

现在,这似乎工作正常 - 堆足够大,可以运行应用程序数天,这里没有泄漏。无论如何,Java 进程会随着时间的推移不断增长,直到所有 128G 都被使用并且应用程序因分配失败而崩溃。

我已经阅读了很多关于本机 java 内存泄漏的内容,包括 max 的 glibc 问题。arenas (我们对 glibc 2.13 有喘息,因此在没有 dist 升级的情况下设置 MALLOC_ARENA_MAX=1 或 4 无法修复)。

所以我们尝试了 jemalloc,它给了我们图表:

使用空间使用空间

使用对象使用对象

我不明白这是什么问题,有人有想法吗?

如果我将 jemalloc 的 MALLOC_CONF="narenas:1" 设置为运行我们的应用程序的 tomcat 进程的环境参数,那仍然可以以某种方式使用 glibc malloc 版本吗?

这是我们的 G1 设置,这里可能有些问题?

-XX:+UseCompressedOops
-XX:+UseNUMA
-XX:NewSize=6000m
-XX:MaxNewSize=6000m
-XX:NewRatio=3
-XX:SurvivorRatio=1
-XX:InitiatingHeapOccupancyPercent=55
-XX:MaxGCPauseMillis=1000
-XX:PermSize=64m
-XX:MaxPermSize=128m
-XX:+PrintCommandLineFlags
-XX:+PrintFlagsFinal
-XX:+PrintGC
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintTenuringDistribution
-XX:-UseAdaptiveSizePolicy
-XX:+UseG1GC
-XX:MaxDirectMemorySize=2g
-Xms65536m
-Xmx65536m

谢谢你的帮助!

4

1 回答 1

0

我们从未显式调用 System.gc(),同时停止使用 G1,没有指定 xms 和 xmx 以外的任何内容。

因此,现在几乎所有的 128G 都用于堆。Java 进程内存使用率很高 - 但数周内保持不变。我确定这是一些 G1 或至少是一般的 GC 问题。这种“解决方案”的唯一缺点是高 GC 暂停,但随着堆的增加,它们从 90 秒减少到大约 1-5 秒,这对于我们使用服务器驱动的基准测试来说是可以的。

在此之前,我使用了 -XX:ParallelGcThreads 选项,当从 28(默认为 40 cpu)下降到 1 时,它对内存泄漏速度有显着影响。内存图看起来有点像在不同实例上使用不同值的手扇...

在此处输入图像描述

于 2017-09-01T14:40:39.560 回答