日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java9 堆外内存_java堆外内存泄漏排查

發(fā)布時間:2025/3/8 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java9 堆外内存_java堆外内存泄漏排查 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

當(dāng)考慮Java中的內(nèi)存泄漏時,我們通常會考慮Java堆泄漏,即在堆中分配的對象沒有被垃圾收集。這是我在處理一臺服務(wù)器內(nèi)存泄漏時的想法,但我即將經(jīng)歷的遠(yuǎn)超出我的想象。

癥狀:運行Vertx應(yīng)用程序(沒有交換分區(qū))的生產(chǎn)服務(wù)器被Linux內(nèi)存不足kill掉(操作系統(tǒng)機制,當(dāng)系統(tǒng)出現(xiàn)內(nèi)存緊張的情況時釋放內(nèi)存)崩潰。

因為它是生產(chǎn)服務(wù)器,所以我認(rèn)為可以讓我們使用堆轉(zhuǎn)儲和MAT來檢查發(fā)生了什么,并嘗試找出誰在消耗這么多內(nèi)存。

結(jié)果令人驚訝,java堆是合理的,遠(yuǎn)遠(yuǎn)少于進(jìn)程內(nèi)存的足跡。有什么東西侵蝕了我的內(nèi)存,我不知道那是什么。

我的出發(fā)點是在home目錄中創(chuàng)建的java致命錯誤日志,所以我開始研究這些日志。您可以在下面的頁面中關(guān)于java致命錯誤日志的信息:致命錯誤日志致命錯誤日志可以提供很多有價值的信息并節(jié)省時間,因此我建議您仔細(xì)閱讀。致命錯誤日志顯示堆大小小于2G,但進(jìn)程正在增長到大約3-4G字節(jié),這是怎么回事?

Java進(jìn)程包含以下內(nèi)存空間:

堆-分配對象的位置。

線程堆棧-包含所有線程堆棧。

Metaspace-包含元數(shù)據(jù)類(替換Java7和更早版本中的PermGen)。

代碼緩存-JIT編譯器代碼緩存。

堆緩沖池不足。

操作系統(tǒng)內(nèi)存-本機操作系統(tǒng)內(nèi)存。

我用了命令:

jmap -heap [pid]

它打印了JVM堆大小的摘要,還顯示了堆大小約為1.5GByte。

我檢查了元空間的大小,但只有幾兆字節(jié)。也許代碼緩存是問題所在?我再次檢查了致命錯誤日志,我看到只有大約20M。我得出的結(jié)論是,可能我有本機內(nèi)存泄漏即-XX:NativeMemoryTracking=detail,然后使用jcmd實用程序(包含在JDK中)檢查本機內(nèi)存。在下一頁中閱讀有關(guān)NMT的更多信息:NMT結(jié)果包含以下內(nèi)容:

Internal (reserved=1031767KB, committed=1031767KB)

(malloc=1031735KB #7619)

(mmap: reserved=32KB, committed=32KB)

我發(fā)現(xiàn)JVM有大約1Gbyte大小的內(nèi)存。現(xiàn)在我確信我有

我發(fā)現(xiàn)有巨大的malloc(操作系統(tǒng)內(nèi)存分配調(diào)用)內(nèi)存分配,但我仍然不知道是什么原因造成的。我試著用gdb處理內(nèi)存轉(zhuǎn)儲,但效果不好,我得出的結(jié)論是它可能不會有用,所以我搜索了Linux內(nèi)存泄漏檢測工具。我有幾個候選人:

Valgrind

malloc_tracer

前兩個由于某些原因不起作用,所以嘗試了人們推薦的jemalloc。我在應(yīng)用程序啟動腳本中添加了以下行:

MALLOC_CONF=prof_leak:true,prof_final:true,lg_prof_interval:30,lg_prof_sample:17 \

LD_PRELOAD=/usr/local/lib/libjemalloc.so.2 [jre path]/jre/bin/java [app parameters]

一開始jemalloc不起作用,我不得不用configure參數(shù)-enable prof重新編譯它,然后它就開始工作了。關(guān)閉應(yīng)用程序后,jemalloc在工作目錄中創(chuàng)建了reproof文件。

[jemalloc install dir]/bin/jeprof --show_bytes --pdf ‘[jre path]/jre/bin/java' [jeprof file] > [pdf output file name]

jemalloc分析表明,使用malloc os調(diào)用分配內(nèi)存的“Unsafe_AllocateMemory”存在嚴(yán)重泄漏。我原以為我現(xiàn)在就能得到答案,但顯然我錯了。我在谷歌上搜索了一下,發(fā)現(xiàn)不安全的分配內(nèi)存可能與名為sun.misc.Unsafe是執(zhí)行本機內(nèi)存分配的JDK私有類,正如它的名稱所表明的那樣,它是不安全的(Oracle計劃在java9中刪除這個類,但最終它仍保留在不受支持的模塊中)。我搜索了應(yīng)用程序代碼,但沒有找到它的任何用法,我假設(shè)它可能是應(yīng)用程序的一些庫使用的。主要嫌疑人是Netty,Netty是Vertx使用的網(wǎng)絡(luò)庫。Netty提供了很好的性能,但它使用本機內(nèi)存分配來實現(xiàn)這一點。在Netty源代碼中挖掘發(fā)現(xiàn)它正在使用`sun.misc.Unsafe`分配本機內(nèi)存池。Netty包含內(nèi)存泄漏檢測機制,因此我嘗試使用Netty參數(shù):

-Dio.netty.leakDetection.level=advanced But that dind't supply any output.

我試著通過使用其他netty參數(shù)(沒有很好的文檔)來限制netty:

-Dio.netty.noPreferDirect=true

-Dio.netty.allocator.type=unpooled

-Dio.netty.maxDirectMemory=0

但這也不管用。

經(jīng)過多次嘗試,我最終發(fā)現(xiàn)直接內(nèi)存分配可以通過以下jvm參數(shù)來限制:

-XX:MaxDirectMemorySize=[max memory]

在深入研究jvm之后,我終于找到了解決方案。我學(xué)到了很多關(guān)于jvm機制和內(nèi)存空間的知識。

總結(jié)

以上是生活随笔為你收集整理的java9 堆外内存_java堆外内存泄漏排查的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。