2016-07-04 66 views
3

我已經寫了一個java應用程序,並且我已經在Fedora 24下運行了java進程。然後我檢查了jconsole並發現它使用了大約5到10兆字節的內存。 垃圾收集的效果也可以在圖中看到。這個java進程爲什麼不釋放內存?

下面是截圖: jconsole screenshot

然後我檢查我的系統監視器,發現了相同的進程ID已超過100兆字節的內存使用情況。

下面是截圖:

System Monitor screenshot

請告訴我,爲什麼不釋放過程中未使用的內存?

有什麼辦法可以釋放它嗎?

+1

什麼是這個Java應用程序?搖擺? –

+0

@CoderinoJavarino no。這些名字可以在他們的標題和我的文字中看到。 –

+0

你爲什麼在意?這是intellij,一個非常大的基於Java的程序。至少在所示的兩個流程中,您並不是抱怨Chrome在超過100MB的情況下。 100MB並不是真正的內存 - 你的Gnome進程將需要更多。如果您真的有問題,請告訴我們。 100MB的內存已經不再是了。 – stdunbar

回答

1

是有區別的使用堆和分配堆之間後持有的所有多餘的堆上。圖中的藍線是已使用的堆 - 堆中有多少實際上是存放對象的。沒有顯示的是分配的堆的大小 - 這是更大的,通常要大得多,以便JVM可以分配更多的對象,而不會耗盡空間並且不得不返回到操作系統以獲得更多內存(這是昂貴的)。在你的情況下,系統顯示的100MB中有一些是JVM本身,但其中大部分可能是已分配但未使用的堆。

當你運行一個Java程序而不指定希望它使用的堆大小時,JVM會嘗試根據你的機器,操作系統,JVM版本等來找出一個合理的設置。當我剛剛運行一個簡單的Hello World我的機器具有16GB的RAM和Java 8,它最初爲堆分配了256mb。顯然遠遠超過它的需要!如果我想強制它使用較少,我可以使用-Xms命令行設置初始堆分配,並設置允許的最大值。我的猜測是,如果你設置了類似-Xms20m的東西,你會看到你的進程使用的內存更少。在IntelliJ中,將該設置添加到運行配置中的VM Options字段。

2

系統監視器中報告的內存是進程使用的所有內存,而不僅僅是Java堆。該存儲器包括:虛擬機本身的

  • 可執行文件和庫已經加載
  • 工作空間,爲VM 作爲一個過程在這樣的事情作爲熱點編譯器,GC,IO緩衝區,屏幕和圖形緩存,讀取VM文件等
  • Java堆和其他報告的內存結構

在你的情況下,過程的10MB被用於存儲Java堆棧和Java對象。另外90MB是Java程序本身和VM內部的內存。

這是簡短的答案,但還有一個重要的考慮因素 - Java可以(並且確實)將多餘的堆釋放回操作系統。這由-XX:MinHeapFreeRatio-XX:MaxHeapFreeRatio標誌控制。默認情況下,MaxHeapFreeRatio是70% - 這幾乎就是您的堆圖(鋸齒圖案從6MB到10MB以下)所顯示的內容。如果您的應用程序具有明顯較大的下降,您將在系統監視器中看到Java進程的(小)鋸齒圖案。

爲了提高性能,您通常應該允許JVM保留從GC中釋放的大量堆。爲什麼?因爲我們知道JVM將立即需要重新開始分配內存,並且對於Java的進程(以及操作系統)來說更有效率來保持這一點。

因此,簡言之:

  • 系統監視器顯示了整個JVM進程
  • Java堆使用的內存僅在過程
  • 它是使用內存的項目之一(一般情況下)JVM在GC之後可以保存(至少部分)堆,因爲我們幾乎肯定會在接下來的幾秒鐘內使用它
  • 這種情況下的Java堆在正常範圍,以及默認的內存配置案允許Java到GC