2010-09-23 65 views
3

我在Linux(64位)上使用Eclipse 3.6和最新的Sun Java 6,並使用大量大型項目。在某些特殊情況下(例如SVN更新),Eclipse需要高達1 GB的堆。但大部分時間只需要350 MB。當我使堆狀態面板,然後我看到大部分的時間:Eclipse發佈堆回到系統

350M的8.78

我啓動Eclipse使用這些設置:-Xms128m -Xmx1024m

所以大部分的時間很多MB的只是在短時間內存使用達到高峯時纔會被浪費掉。我不喜歡這一點,我希望Eclipse將內存釋放回系統,所以我可以將它用於其他程序。

當Eclipse需要更多內存,而沒有足夠的可用RAM時,Linux可以將其他正在運行的程序換掉,我可以忍受這一點。我聽說有一個-XX:MaxHeapFreeRatio選項。但我從來沒有想出我必須使用什麼樣的價值,所以它的工作原理。我嘗試過的任何價值都沒有改變。

那麼,我該如何告訴Eclipse(或Java)釋放未使用的堆?

+0

你用Xms Xmx設置試試這個eclipse.ini(http://stackoverflow.com/questions/142357/what-are-the-best-jvm-settings-for-eclipse/3275659#3275659)嗎? – VonC 2010-09-23 07:39:00

回答

11

找到了解決辦法。我將Java切換爲使用G1垃圾回收器,現在HeapFreeRatio參數按預期工作。所以,我的eclipse.ini中使用這些選項:

-XX:+UnlockExperimentalVMOptions 
-XX:+UseG1GC 
-XX:MinHeapFreeRatio=5 
-XX:MaxHeapFreeRatio=25 

現在,當Eclipse的吞噬了超過1 GB的RAM對於複雜的操作和垃圾收集後切換回300 MB內存實際上是釋放回操作系統。

2

你可以去Preferences -> General並檢查Show heap status。這可以在Eclipse的角落激活堆的美景。事情是這樣的:

alt text

如果單擊回收站,它會嘗試運行垃圾收集和返回的內存。

+2

我知道這個狀態顯示(甚至在我的問題中提到它),我知道這個垃圾按鈕,但它只運行垃圾回收器,並且不向系統返回任何內存。因此,如果Eclipse的內存使用高峯期爲1 GB,那麼即使實際只使用了300 MB的堆,堆的大小也會永遠保持在1 GB(直到我重新啓動Eclipse)。 – kayahr 2010-09-23 11:02:23

1

Java的堆只不過是在JVM進程堆空間內管理的大數據結構。即使它們佔用相同的內存,這兩個堆也是邏輯上分離的實體。

JVM受到主機系統實施malloc()的擺佈,該系統使用brk()從系統分配內存。在Linux系統上(也是Solaris),分配給進程堆的內存幾乎從不返回,主要是因爲它變成了碎片並且堆必須是連續的。這意味着分配給進程的內存將單調增加,而保持大小的唯一方法不是首先分配它。

-Xms-Xmx告訴JVM如何提前調整Java堆的大小,這會導致它分配進程內存。 Java可以收集垃圾直到太陽燒盡,但這種清理是JVM的內部處理,支持它的進程內存不會返回。


從下面的評論闡述:

爲C語言編寫的程序(特別是JVM上運行Eclipse你)來分配內存的標準方法是調用malloc(3),它使用操作系統提供的機制爲流程分配內存,然後管理這些分配內的各個分配。 malloc()free()如何工作的細節是特定於實現的。

在大多數Unix系統中,一個進程只能得到一個數據段,這個數據段是指向開始和結束的連續內存區域。通過調用brk(2)並增加結束指針來分配更多內存或減少它返回給系統,該過程可以調整此段的大小。只有結束可以調整。這意味着如果您的malloc()的實現放大了數據段,則free()的相應實現不能收縮它,除非它確定末尾有空間不被使用。在實踐中,當你分配給malloc()的大量內存很少會在數據段的最後結束,因爲它會導致進程趨於單調增長。

+0

這是否意味着這是一個操作系統問題,並且在Windows上正確地將內存返回給系統?有沒有官方消息稱它不適用於Linux? – kayahr 2010-09-23 11:04:22

+0

這不是一個操作系統問題。在你的情況中,它是JVM爲Java堆分配了多少進程內存,它是如何釋放以及JVM使用的分配器(通常是libc的'malloc()')如何處理進程內存的組合。我在最初的回答中詳細闡述了它。任何關於特定實現行爲的「官方聲明」都將成爲該實現的來源。 – Blrfl 2010-09-23 13:30:13