我已經寫了一個java應用程序,並且我已經在Fedora 24下運行了java進程。然後我檢查了jconsole並發現它使用了大約5到10兆字節的內存。 垃圾收集的效果也可以在圖中看到。這個java進程爲什麼不釋放內存?
然後我檢查我的系統監視器,發現了相同的進程ID已超過100兆字節的內存使用情況。
下面是截圖:
請告訴我,爲什麼不釋放過程中未使用的內存?
有什麼辦法可以釋放它嗎?
我已經寫了一個java應用程序,並且我已經在Fedora 24下運行了java進程。然後我檢查了jconsole並發現它使用了大約5到10兆字節的內存。 垃圾收集的效果也可以在圖中看到。這個java進程爲什麼不釋放內存?
然後我檢查我的系統監視器,發現了相同的進程ID已超過100兆字節的內存使用情況。
下面是截圖:
請告訴我,爲什麼不釋放過程中未使用的內存?
有什麼辦法可以釋放它嗎?
是有區別的使用堆和分配堆之間後持有的所有多餘的堆上。圖中的藍線是已使用的堆 - 堆中有多少實際上是存放對象的。沒有顯示的是分配的堆的大小 - 這是更大的,通常要大得多,以便JVM可以分配更多的對象,而不會耗盡空間並且不得不返回到操作系統以獲得更多內存(這是昂貴的)。在你的情況下,系統顯示的100MB中有一些是JVM本身,但其中大部分可能是已分配但未使用的堆。
當你運行一個Java程序而不指定希望它使用的堆大小時,JVM會嘗試根據你的機器,操作系統,JVM版本等來找出一個合理的設置。當我剛剛運行一個簡單的Hello World我的機器具有16GB的RAM和Java 8,它最初爲堆分配了256mb。顯然遠遠超過它的需要!如果我想強制它使用較少,我可以使用-Xms
命令行設置初始堆分配,並設置允許的最大值。我的猜測是,如果你設置了類似-Xms20m
的東西,你會看到你的進程使用的內存更少。在IntelliJ中,將該設置添加到運行配置中的VM Options
字段。
系統監視器中報告的內存是進程使用的所有內存,而不僅僅是Java堆。該存儲器包括:虛擬機本身的
在你的情況下,過程的10MB被用於存儲Java堆棧和Java對象。另外90MB是Java程序本身和VM內部的內存。
這是簡短的答案,但還有一個重要的考慮因素 - Java可以(並且確實)將多餘的堆釋放回操作系統。這由-XX:MinHeapFreeRatio
和-XX:MaxHeapFreeRatio
標誌控制。默認情況下,MaxHeapFreeRatio是70% - 這幾乎就是您的堆圖(鋸齒圖案從6MB到10MB以下)所顯示的內容。如果您的應用程序具有明顯較大的下降,您將在系統監視器中看到Java進程的(小)鋸齒圖案。
爲了提高性能,您通常應該允許JVM保留從GC中釋放的大量堆。爲什麼?因爲我們知道JVM將立即需要重新開始分配內存,並且對於Java的進程(以及操作系統)來說更有效率來保持這一點。
因此,簡言之:
什麼是這個Java應用程序?搖擺? –
@CoderinoJavarino no。這些名字可以在他們的標題和我的文字中看到。 –
你爲什麼在意?這是intellij,一個非常大的基於Java的程序。至少在所示的兩個流程中,您並不是抱怨Chrome在超過100MB的情況下。 100MB並不是真正的內存 - 你的Gnome進程將需要更多。如果您真的有問題,請告訴我們。 100MB的內存已經不再是了。 – stdunbar