Java 在Tomcat中提示内存溢出(OutOfMemoryError)的原因和处理方式

Tomcat sxdgy 1907℃

很多开发运维人员都有遇到过java.lang.OutOfMemoryError这个错误,原因无外乎两点:JVM内存过小、程序不严密产生了过多的垃圾。具体来说有以下几种:

  • JVM启动参数内存值设定的过小。
  • 内存中加载的数据量过于庞大,如一次从数据库取出过多数据。
  • 集合类中有对象引用,使用完后未清空,使得JVM不能回收;
  • 代码中存在死循环或循环产生过多重复的对象实体;
  • 使用的第三方软件中的有BUG;

此类错误在Tomcat中常见的错误提示有两种:

java.lang.OutOfMemoryError: PermGen space
java.lang.OutOfMemoryError: Java heap space

第一条中的PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,也称”永久代”,用于存储虚拟机(JVM)加载的类(class)信息、常量、静态变量、是各个线程共享的内存区域。类在被载入(Loader)时就被放到该区中。GC(Garbage Collection垃圾回收机制)不会在主程序运行期对该区进行清理。所以如果程序中有很多类的话,就很可能出现java.lang.OutOfMemoryError: PermGen space错误, 这种错误常见在web服务器对JSP进行预编译(pre compile)的时候。如果WEB APP下都用了大量的第三方jar,其大小超过了jvm设置默认的大小(不同JVM默认值不尽相同,网上常说的默认最小值为16MB,最大值为64MB),那么就会产生此错误信息了。 简单粗暴的解决方法是在TOMCAT_HOME/bin/catalina.sh中通过手动指定-XX:PermSize、-XX:MaxPermSize参数限制该区的大小。

第二条中的Heap space是指堆区,是指java程序运行过程中JVM可以调配使用的内存空间,Heap的大小是年轻代(Young Generation)和老年代(Tenured Generaion)之和。默认其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。

最后说下TOMCAT_HOME/bin/catalina.sh设置JAVA_OPTS格式和说明:

#常用格式:
JAVA_OPTS="-server -Xms512m -Xmx1024m -Xss2048K -XX:PermSize=512m -XX:MaxPermSize=1024m"
#参数说明:
-server:一定要作为第一个参数,在多个CPU时性能佳
-Xms:初始Heap大小,使用的最小内存,cpu性能高时此值应设的大一些
-Xmx:指定heap最大值,使用的最大内存
-XX:PermSize: 设定内存的永久保存区域
-XX:MaxPermSize:设定最大内存的永久保存区域
+XX:AggressiveHeap 会使得 Xms没有意义。这个参数让jvm忽略Xmx参数,疯狂地吃完一个G物理内存,再吃尽一个G的swap。
-Xss:每个线程的Stack大小
-verbose:gc 现实垃圾收集信息
-Xloggc:gc.log 指定垃圾收集日志文件
-Xmn:young generation的heap大小,一般设置为Xmx的3-4分之一
-XX:+UseParNewGC :缩短minor收集的时间
-XX:+UseConcMarkSweepGC :缩短major收集的时间。提示:此选项在Heap Size 比较大而且Major收集时间较长的情况下使用更合适。

转载请注明:零五博客 » Java 在Tomcat中提示内存溢出(OutOfMemoryError)的原因和处理方式