JVM啟動參數與java.lang.OutOfMemoryError
來源:互聯網
上載者:User
前言
java.lang.OutOfMemoryError,這個主要是JVM參數沒有配好引起的。
OutOfMemoryError分兩種:java.lang.OutOfMemoryError: Java heap space和java.lang.OutOfMemoryError: PermGen space。
前者是有關堆記憶體的記憶體溢出,可以通過配置-Xms和-Xmx參數來解決。
後者是有關非堆記憶體的記憶體溢出,可以通過配置-XX:PermSize和-XX:MaxPermSize來設定。
參數的含義
-Xms:JVM初始分配的堆記憶體
-Xmx:JVM最大允許分配的堆記憶體,按需分配
-XX:PermSize:JVM初始分配的非堆記憶體
-XX:MaxPermSize:JVM最大允許分配的非堆記憶體,按需分配 在Intellij IDEA中的Tomcat容器中進行設定,如下圖所示:
堆記憶體和非堆記憶體
堆記憶體:
JVM留給開發人員用的記憶體。一般存放對象以及數組。JVM初始分配的堆記憶體由-Xms指定,預設是實體記憶體的1/64;JVM最大分配的堆記憶體由-Xmx指定,預設是實體記憶體的1/4。空餘堆記憶體小於40%時,JVM就會增大堆記憶體直到-Xmx的最大限制;空餘堆記憶體大於70%時,JVM會減少堆記憶體直到-Xms的最小限制。因此伺服器一般設定-Xms、-Xmx相等以避免在每次GC後調整堆記憶體的大小。如果-Xmx不指定或者指定偏小,應用可能會導致java.lang.OutOfMemory錯誤,此錯誤來自JVM,不是Throwable的,無法用try...catch捕捉。
非堆記憶體:
JVM留給自己用的記憶體。方法區、JVM內部處理或最佳化所需的記憶體(如JIT編譯後的代碼緩衝)、每個類結構(如運行時常數池、欄位和方法資料)以及方法和構造方法的代碼都在非堆記憶體中。JVM初始分配的非堆記憶體由-XX:PermSize指定,預設是實體記憶體的1/64;JVM最大分配的非堆記憶體由-XX:MaxPermSize指定,預設是實體記憶體的1/4。(還有一說:MaxPermSize預設值和-server -client選項相關,-server選項下預設MaxPermSize為64m,-client選項下預設MaxPermSize為32m)
-XX:MaxPermSize設定過小會導致java.lang.OutOfMemoryError: PermGen space,原因如下:
PermGen space用於存放Class和Meta的資訊,GC不會對PermGen space進行處理,所以如果Load很多Class的話,就會出現上述Error。這種Error在web伺服器對JSP進行pre compile的時候比較常見。 在用Spark載入模型時,遇到了
java.lang.OutOfMemoryError: PermGen space這個錯誤,導致這個錯誤的主要原因是載入的模型中有大量的metadata資訊,該部分全部放在非堆記憶體中,對非堆記憶體進行設定後,不再報該錯誤。