簡體   English   中英

JConsole堆轉儲比內存使用量小得多

[英]JConsole heap dump much smaller than memory usage

我們有一些容器通過docker運行Java進程。 我們注意到的一件事是,僅通過運行一個簡單的spring-boot應用程序就占用了大量內存,甚至不包含我們自己的代碼(只是嘗試獲取某種內存配置文件,而與我們可能引入的任何問題無關) )。

我看到的是docker / JVM占用的內存徘徊在2.5左右。 我們確實包含了相當多的額外部門(駱駝,冬眠,一些春季靴子部門),但這並不是真正讓我失望的東西。 我看到的是,盡管Docker表示它已為該應用程序消耗了2.5GB的內存,但對它運行jconsole卻顯示它消耗了多達1GB的內存(GC並緩慢攀升后降至約200MB)。 泊塢窗上的內存空間也保持在GC之后的水平(2.5GB)。

此外,當我轉儲堆以查看哪些對象正在占用該空間時,將.hprof文件加載到MAT中后,堆看起來只有33MB。 這些對我來說都沒有多大意義。 目前,我正在查看jconsole中報告的非堆空間為115MB,而堆空間為331MB。

我已經(在SO和其他站點上)讀過很多關於JVM內存區域的信息,並且有些事情專門報告說堆轉儲可能較小,但是我所知道的都沒有那么遠,除此之外,許多建議要注意的事情是,每當進行堆轉儲時,GC都會運行,並且MAT具有顯示或隱藏無法訪問的對象的設置。 在發布到這里之前,已經考慮了所有這些問題,現在我感覺好像有其他事情在起作用,我無法捕捉自己,也沒有在網上找到。

我完全期望這些數字可能會有些許偏離,但是在最佳情況下,它們似乎相差十倍,而在查看docker報告的內存使用情況時,相差近一百倍。

有人知道我在這里可能會想念的嗎?

編輯:這也是一個運行Java 8的應用程序,尚未運行Java11。它在JIRA板上有待執行,但尚未計划。

EDIT2:添加屏幕截圖。 JConsole屏幕截圖中的峰值來自運行GC。

帶有內存使用情況的Docker統計信息

JConsole堆內存使用情況

MAT堆轉儲

JConsole為您提供了已落實的內存量:3311616 KiB〜= 3GiB這是Java進程消耗的內存量,如操作系統所示。

這與當前用於容納Java對象的堆大小無關,JConsole也將其報告為130237 KB〜= 130 MiB。

這也與實際存在的對象數無關:默認情況下,當您加載堆轉儲時,MAT將刪除無法訪問的對象。 您可以通過轉到首選項->內存分析器->保留無法訪問的對象來啟用該選項(請參閱MAT文檔 )。 因此,如果您有很多短暫的對象,則差異可能會很大。

我看到它還報告了大約9GiB的最大堆。 這意味着您已將Xmx參數設置為較大的值。

熱點GC在回收未使用的內存方面不是很好。 他們傾向於使用所有可用的空間(最大堆大小,由Xmx設置),然后從不取消使用堆,從而有效地將其保留給Java進程使用,而不是釋放給OS。

如果要從OS的角度最大程度地減少進程的內存占用量,建議您設置較低的Xmx,也許是-Xmx1g,以免Java增長太多(當然,Xmx也需要很高)足以容納您的應用程序工作量!)。

如果確實需要自適應堆,那么您也可以切換到G1(-XX:+ UseG1GC)和更新的Java,因為熱點團隊最近已進行了一些改進

戴夫

操作系統監視工具將向您顯示進程分配的內存量。 所以這: 在此處輸入圖片說明 意味着您的Java進程分配了2.664G的內存(Java堆+元空間)

JConsole向您顯示內存中的代碼正在“消耗”(忽略元空間)

我看到2種可能的解釋:

  1. 您為-Xms設置了巨大的價值
  2. 您在元空間上加載了很多靜態代碼(或其他內容)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM