1. 程式人生 > >Eclipse虛擬記憶體不足解決方法

Eclipse虛擬記憶體不足解決方法

Eclipse最近在做J2EE專案中 發現老是出現虛擬記憶體不足的提示
前2天去加了根記憶體 問題同樣存在
為了讓我在寫程式碼時 不在出現那討厭的記憶體不足的提示 也為了
不讓那破機器再卡住 今天找到了解決方法 試過後好象確實沒出
記憶體不足的提示了
提示大概如下:
MyEclipse has detected that less than 5% of the 64MB of Perm
Gen (Non-heap memory) space remains. It is strongly recommended
that you exit and restart MyEclipse with new virtual machine memory
paramters to increase this memory.  Failure to do so can result in
data loss. The recommended Eclipse

memory parameters are:
eclipse.exe -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M

解決方法:
找到Eclipse安裝檔案下的eclipse.ini配置檔案
通常裡面都是寫的-vmargs-Xms40m-Xmx256m
-vmargs:說明後面是VM的引數
-Xms40m:虛擬機器佔用系統的最小記憶體
Xmx256m:虛擬機器佔用系統的最大記憶體
-XX:PermSize:最小堆大小.一般報記憶體不足時,都是說這個太小,
                       堆空間剩餘小於5%就會警告,建議把這個稍微設
                               大一點,不過要視自己機器記憶體大小來設定
-XX:PermSize:最大堆大小.這個也適當大些

把裡面的引數改為
-vmargs 
-Xms128M 
-Xmx512M 
-XX:PermSize=128M 
-XX:MaxPermSize=256M

=================方法2===============

如果沒有進行設定的話,在使用MyEclipse的經常出現如下圖所示記憶體不足的提示。
myeclipse.png
提示中說的很明白:“MyEclipse has detected that less than 5% of the 64MB of Perm Gen (Non-heap memory) space remains.”意思是說當前只有小於5%的非堆記憶體是空閒的。所以我們只要將這個值設定大一些就可以了。

提示中給出了設定的引數:

  1. -vmargs -Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M

這裡有幾個問題:
1. 各個引數的含義什麼?
2. 為什麼有的機器我將-Xmx和-XX:MaxPermSize都設定為512M之後Eclipse可以啟動,而有些機器無法啟動?
3. 為何將上面的引數寫入到eclipse.ini檔案Eclipse沒有執行對應的設定?

下面我們一一進行回答

1. 各個引數的含義什麼?

引數中-vmargs的意思是設定JVM引數,所以後面的其實都是JVM的引數了,我們首先了解一下JVM記憶體管理的機制,然後再解釋每個引數代表的含義。

  • 堆(Heap)和非堆(Non-heap)記憶體
    按照官方的說法:“Java 虛擬機器具有一個堆,堆是執行時資料區域,所有類例項和陣列的記憶體均從此處分配。堆是在 Java 虛擬機器啟動時建立的。”“在JVM中堆之外的記憶體稱為非堆記憶體(Non-heap memory)”。可以看出JVM主要管理兩種型別的記憶體:堆和非堆。簡單來說堆就是Java程式碼可及的記憶體,是留給開發人員使用的;非堆就是JVM留給自己用的,所以方法區、JVM內部處理或優化所需的記憶體(如JIT編譯後的程式碼快取)、每個類結構(如執行時常數池、欄位和方法資料)以及方法和構造方法的程式碼都在非堆記憶體中。
  • 堆記憶體分配
    JVM初始分配的記憶體由-Xms指定,預設是實體記憶體的1/64;JVM最大分配的記憶體由-Xmx指定,預設是實體記憶體的1/4。預設空餘堆記憶體小於40%時,JVM就會增大堆直到-Xmx的最大限制;空餘堆記憶體大於70%時,JVM會減少堆直到-Xms的最小限制。因此伺服器一般設定-Xms、-Xmx相等以避免在每次GC 後調整堆的大小。
  • 非堆記憶體分配
    JVM使用-XX:PermSize設定非堆記憶體初始值,預設是實體記憶體的1/64;由XX:MaxPermSize設定最大非堆記憶體的大小,預設是實體記憶體的1/4。
  • JVM記憶體限制(最大值)
    首先JVM記憶體限制於實際的最大實體記憶體(廢話!呵呵),假設實體記憶體無限大的話,JVM記憶體的最大值跟作業系統有很大的關係。簡單的說就32位處理器雖然可控記憶體空間有4GB,但是具體的作業系統會給一個限制,這個限制一般是2GB-3GB(一般來說Windows系統下為1.5G-2G,Linux系統下為2G-3G),而64bit以上的處理器就不會有限制了。

2. 為什麼有的機器我將-Xmx和-XX:MaxPermSize都設定為512M之後Eclipse可以啟動,而有些機器無法啟動?

通過上面對JVM記憶體管理的介紹我們已經瞭解到JVM記憶體包含兩種:堆記憶體和非堆記憶體,另外JVM最大記憶體首先取決於實際的實體記憶體和作業系統。所以說設定VM引數導致程式無法啟動主要有以下幾種原因:

1) 引數中-Xms的值大於-Xmx,或者-XX:PermSize的值大於-XX:MaxPermSize;

2) -Xmx的值和-XX:MaxPermSize的總和超過了JVM記憶體的最大限制,比如當前作業系統最大記憶體限制,或者實際的實體記憶體等等。說到實際實體記憶體這裡需要說明一點的是,如果你的記憶體是1024MB,但實際系統中用到的並不可能是1024MB,因為有一部分被硬體佔用了。

3. 為何將上面的引數寫入到eclipse.ini檔案Eclipse沒有執行對應的設定?

那為什麼同樣的引數在快捷方式或者命令列中有效而在eclipse.ini檔案中是無效的呢?這是因為我們沒有遵守eclipse.ini檔案的設定規則:

引數形如“項 值”這種形式,中間有空格的需要換行書寫,如果值中有空格的需要用雙引號包括起來。比如我們使用-vm C:/Java/jre1.6.0/bin/javaw.exe引數設定虛擬機器,在eclipse.ini檔案中要寫成這樣:

  1. -vm
  2. C:/Java/jre1.6.0/bin/javaw.exe

按照上面所說的,最後引數在eclipse.ini中可以寫成這個樣子:

  1. -vmargs
  2. -Xms128M
  3. -Xmx512M
  4. -XX:PermSize=64M
  5. -XX:MaxPermSize=128M

實際執行的結果可以通過Eclipse中“Help”-“About Eclipse SDK”窗口裡面的“Configuration Details”按鈕進行檢視。

另外需要說明的是,Eclipse壓縮包中自帶的eclipse.ini檔案內容是這樣的:

  1. -showsplash
  2. org.eclipse.platform
  3. --launcher.XXMaxPermSize
  4. 256m
  5. -vmargs
  6. -Xms40m
  7. -Xmx256m

其中–launcher.XXMaxPermSize(注意最前面是兩個連線線)跟-XX:MaxPermSize引數的含義基本是一樣的,我覺得唯一的區別就是前者是eclipse.exe啟動的時候設定的引數,而後者是eclipse所使用的JVM中的引數。其實二者設定一個就可以了,所以這裡可以把–launcher.XXMaxPermSize和下一行使用#註釋掉。