天天看點

JVM Cannot allocate memory記憶體不足

記憶體不足

現象:

Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/jdk1.8.0_31
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=128m; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=512m; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000a2400000, 1438646272, 0) failed; error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 1438646272 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /usr/local/tomcat/bin/hs_err_pid12336.log
           

tomcat調優參數如下:

# catalina.sh記憶體調優參數
CATALINA_OPTS="-server -Xms256m -Xmx512m -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=12345"
JAVA_OPTS="-Xms1500m -Xmx1500m -Xss1024K -XX:MaxNewSize=128m -XX:-UseGCOverheadLimit"
           

調優參數說明:

// JVM初始配置設定的堆記憶體, 生産環境建
-Xms256m 
// JVM初始配置設定的非堆記憶體, 不會被回收, 生産環境建議與maxPermSize相同, 設為256m以上
-XX:PermSize=64m 
// JVM堆區域新生代記憶體的最大可配置設定大小(PermSize不屬于堆區), 生産環境建議設為800M-1024M
-XX:MaxNewSize=512m 
// JVM最大允許配置設定的非堆記憶體, 生産環境建議設定為256m以上
-XX:MaxPermSize=128M 
//是上面兩個的快捷定義方式, 等同于上面兩個都為512m議與Xmx相同, 設為1024m以上
-Xmn512m 
// JVM最大允許配置設定的堆記憶體, 生産環境建議設為1024m以上
-Xmx512m 
// 線程堆棧大小, JDK5以上一般設定為256k或以上, 與 -XX:ThreadStackSize 的差別
-Xss128k 
// JVM初始配置設定的非堆記憶體, 不會被回收, 生産環境建議與maxPermSize相同, 設為256m以上
-XX:PermSize=64m 
// JVM堆區域新生代記憶體的最大可配置設定大小(PermSize不屬于堆區), 生産環境建議設為800M-1024M
-XX:MaxNewSize=512m 
// JVM最大允許配置設定的非堆記憶體, 生産環境建議設定為256m以上
-XX:MaxPermSize=128M 
// 是上面兩個的快捷定義方式, 等同于上面兩個都為512m
-Xmn512m 
           

分析:

在Tomcat的catalina.sh檔案中的啟停server腳本中都應用到了兩個變量: CATALINA_OPTS和JAVA_OPTS。用于儲存Tomcat運作所需的各種參數。

他們在檔案中的注釋如下:

  • (可選)Java 執行"start","stop"或"run"指令時用到的運作時參數; [JAVA_OPTS]
  • (可選)Java 執行"start"或"run"指令時用到的運作時參數; [CATALINA_OPTS]

那麼,為什麼有兩個不同的變量?他們有什麼差別?

  • 首先,定義在這兩個變量中的參數都會被傳遞到啟動Tomcat的指令:“start"和"run”,隻有定義在JAVA_OPTS中的參數會被傳遞到"stop"指令。是以将參數定義到哪個變量中并不影響Tomcat的啟動和運作,而隻影響到了Tomcat的運作結束。
  • 第二種差別更加微妙。其他應用程式也可以使用JAVA_OPTS,但Tomcat隻會用到CATALINA_OPTS。是以如果你隻使用了Tomcat,在設定環境變量時,你最好使用CATALINA_OPTS,而如果你同時也用到了其他java應用程式,如JBoss,在設定環境變量時你應該使用JAVA_OPTS。

處理建議:

  • tomcat記憶體調優盡量使用CATALINA_OPTS來設定記憶體參數,否則停止的時候也需要調用或者配置設定記憶體,容易導緻記憶體不足
  • 如果隻需要調整堆記憶體參數:

    CATALINA_OPTS="-server -Xms256m -Xmx512m"

繼續閱讀