2017-08-04 148 views
3

我們目前有一個Java本機內存泄漏的問題。服務器相當大(40CPUS,128GB內存)。 Java堆大小是64G,我們運行了一個非常內存密集的應用程序,它將大量數據讀取到大約400個線程的字符串中,並在幾分鐘後將它們從內存中拋出。Java本地內存泄漏與G1和巨大的內存

所以堆堆積得非常快,但是堆上的東西變得過時,並且可以非常快速地被打開。所以我們必須使用G1來讓STW在幾分鐘內不會中斷。

現在,這似乎工作正常 - 堆足夠大,運行應用程序的天,沒有任何泄漏在這裏。無論如何,隨着時間的推移,Java進程正在不斷增長和增長,直到所有128G都被使用,並且應用程序因爲分配失敗而崩潰。

我讀了很多關於原生Java內存泄漏的信息,包括glibc問題,競技場(我們用glibc 2.13喘氣,所以沒有修復可能在這裏設置MALLOC_ARENA_MAX = 1或4沒有dist升級)。

所以我們試圖jemalloc什麼給了我們對於圖表:

INUSE空間inuse-space

INUSE對象inuse-objects

我不明白這裏有什麼問題,有人有想法嗎?

如果我爲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 

感謝您的幫助!

+0

這將是非常難以分析這個問題,通過與內存光看着它。我會建議使用Dynatrace等工具來監視進程,以更好地理解內存分配,GC吞吐量和CPU利用率。 – Armaiti

+0

我今天已經隔離了一個G1本機內存泄漏,它只發生在重負載和頻繁使用System.gc()的情況下。我在OS X上使用了XCode,首先看到本地堆中泄露的數據是數百萬和數百萬個32字節的malloc,然後我使用dtrace確定絕大多數這些32字節的malloc來自G1。 –

回答

0

我們從不顯式調用System.gc(),同時停止使用G1,沒有指定除xms和xmx以外的任何內容。

因此現在使用幾乎所有的128G。 java進程的內存使用率很高 - 但是持續數週。我相信這是一些G1或至少一般的GC問題。這個「解決方案」的唯一缺點是高GC暫停,但隨着堆的增加,它們從90秒降低到1-5秒左右,這對我們用服務器驅動的基準來說是好的。

在此之前,我使用了-XX:ParallelGcThreads選項,它在從28(默認爲40 cpus)向下降低到1時對內存泄漏速度有顯着影響。內存圖看起來有點像使用不同的手扇在不同的情況下,值...

enter image description here