iT邦幫忙

0

淺談 JVM PermGen space 的解決方法

  • 分享至 

  • xImage
  •  

CATALINA_OPTS="-Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=1024m"
export CATALINA_OPTS

JAVA_OPTS="-Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=1024m"
export JAVA_OPTS

說明:

-Xms = 初始值
-Xmx = 最大值
-Xmn = 最小值

-XX:PermSize = 設定記憶體的永久保存區域
-XX:MaxPermSize = 設定最大記憶體的永久保存區域
-XX:MaxNewSize = 設置新域的最大值

Xms 、Xmx、XX:PermSize、XX:MaxPermSize 各個引數的含義;

我們首先了解一下 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,由X:MaxPermSize 設定最大非堆記憶體的大小,預設是實體記憶體的1/4。

JVM 記憶體限制(最大值):

首先 JVM 記憶體限制於實際的最大實體記憶體,假設實體記憶體無限大的話,JVM 記憶體的最大值跟作業系統有很大的關係。

簡單的說就32bit處理器雖然可控記憶體空間有4GB,但是具體的作業系統會給一個限制,這個限制一般是2GB-3GB(一般來說 Windows 系統下為1.5G-2G,Linux 系統下為2G-3G),而64bit以上的處理器就不會有限制了。

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

通過上面對 JVM 記憶體管理的介紹我們已經瞭解到 JVM 記憶體包含兩種:堆記憶體和非堆記憶體,另外 JVM 最大記憶體首先取決於實際的實體記憶體和作業系統。

所以說設定 VM 引數導致程序無法啟動主要有以下幾種原因:

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

(2) -Xmx 的值和 -XX:MaxPermSize 的總和超過了 JVM 記憶體的最大限制,比如當前作業系統最大記憶體限制,或者實際的實體記憶體等等。

說到實際實體記憶體這裡需要說明一點的是,如果你的記憶體是1024MB,但實際系統中用到的並不可能是1024MB,因為有一部分被硬體佔用了。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言