带有G1和巨大内存的Java本机内存泄漏

带有G1和巨大内存的Java本机内存泄漏,java,memory-leaks,g1gc,jemalloc,Java,Memory Leaks,G1gc,Jemalloc,我们目前存在java本机内存泄漏问题。服务器相当大(40CPU,128GB内存)。Java堆大小是64G,我们运行一个非常占用内存的应用程序,用大约400个线程将大量数据读取到字符串中,并在几分钟后将其从内存中丢弃 所以堆很快就填满了,但是堆上的东西变得过时了,并且可以很快地进行GCD。因此,我们必须使用G1,使STW在几分钟内没有中断 现在,这似乎工作得很好-堆足够大,可以运行应用程序数天,这里没有泄漏。无论如何,Java进程一直在增长,直到所有128G都被使用,应用程序因分配失败而崩溃 我读

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

所以堆很快就填满了,但是堆上的东西变得过时了,并且可以很快地进行GCD。因此,我们必须使用G1,使STW在几分钟内没有中断

现在,这似乎工作得很好-堆足够大,可以运行应用程序数天,这里没有泄漏。无论如何,Java进程一直在增长,直到所有128G都被使用,应用程序因分配失败而崩溃

我读过很多关于本机java内存泄漏的文章,包括max.arenas的glibc问题(我们在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
谢谢你的帮助

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

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

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


用记忆光学的方法来分析这个问题确实很难。我建议您使用Dynatrace等工具来监控进程,以便更好地了解内存分配、GC吞吐量和CPU利用率。今天,我隔离了一个G1本机内存泄漏,该泄漏仅在重载和频繁使用System.GC()时发生。我在OSX上使用XCode首先看到本机堆中泄漏的数据是数百万个32字节malloc,然后我使用dtrace确定这些32字节malloc中的绝大多数来自G1。