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"

你可能感兴趣的:(异常)