第1章 JAVA内存溢出详解
常见的Java内存溢出有以下三种
1.1 java.lang.OutOfMemoryError: Java heap space
JVM Heap(堆)溢出
JVM在启动的时候会自动设置JVM Heap的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)不可超过物理内存。
可以利用JVM提供的-Xmn -Xms -Xmx等选项进行设置。Heap的大小是Young Generation 和Tenured Generaion 之和。
在JVM中如果98%的时间是用于GC,且可用的Heap size 不足2%的时候将抛出此异常信息。
解决方法:手动设置JVM Heap(堆)的大小。
1.2 java.lang.OutOfMemoryError: PermGen space
PermGen space溢出。
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。
为什么会内存溢出,这是由于这块内存主要是被JVM存放Class和Meta信息的,Class在被Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同,sun的 GC不会在主程序运行期对PermGen space进行清理,所以如果你的APP会载入很多CLASS的话,就很可能出现PermGen space溢出。
解决方法: 手动设置MaxPermSize大小
1.3 java.lang.StackOverflowError
栈溢出
栈溢出了,JVM依然是采用栈式的虚拟机,这个和C和Pascal都是一样的。函数的调用过程都体现在堆栈和退栈上了。
调用构造函数的 “层”太多了,以致于把栈区溢出了。
通常来讲,一般栈区远远小于堆区的,因为函数调用过程往往不会多于上千层,而即便每个函数调用需要 1K的空间(这个大约相当于在一个C函数内声明了256个int类型的变量),那么栈区也不过是需要1MB的空间。通常栈的大小是1-2MB的。
通常递归也不要递归的层次过多,很容易溢出。
解决方法:修改程序。
第2章 解决方法
2.1 参数示例说明
JAVA_OPTS='-Xms【初始化内存大小】 -Xmx【可以使用的最大内存】'
需要把这个两个参数值调大。例如:
JAVA_OPTS='-Xms256m –Xmx768m'
表示初始化内存为256MB,可以使用的最大内存为768MB。
【可以使用的最大内存】:建议设为物理内存的50%~80%。不可超过物理内存。
建议把内存的最高值跟最低值的差值缩小,不然会浪费很多内存的,最低值加大,最高值可以随便设,但是要根据实际的物理内存,如果内存设置太大了,比如设置了758M最大内存,但如果没有768M可用内存,Tomcat就不能启动,还有可能存在内存被系统回收,终止进程的情况。
或者将Xms和Xmx两个值设置大小为一样的,这样可以避免在程序运行完毕内存GC时还需要重新调整内存,提高效率。
以下为XXX正式服务器中设置的内存值大小,供类似生产设备设置参考
Windows Server 2003,内存8G
2.2 在Linux环境下的Tomcat(免安装版本)
修改TOMCAT_HOME/bin/catalina.sh
在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="$JAVA_OPTS -server -Xms256m –Xmx768m -XX:PermSize=256M -XX:MaxPermSize=768m"
$JAVA_OPTS是保留先前设置。
2.3 在Windows环境下的Tomcat(免安装版本)
64位机器:
如果已经注册到windows服务,并且服务名称非tomcat6,需要进行移除服务,重新命名
进入apache-tomcat-6.0.29/bin目录,双击tomcat6w.exe ,按红色标注位置进行设置
-XX:PermSize=256M
-XX:MaxPermSize=768M
32位机器
如果Tomcat 已经注册成了windows服务,以服务方式启动的:
修改注册表中的JvmMs和JvmMx键值。
修改注册表HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\....\Parameters\Java,
右侧的JvmMs和JvmMx(十进制参考值JvmMs:256,JvmMx:768)
2.4 安装版
前几种方法针对的是bin目录下有catalina.bat的情况(比如直接解压的Tomcat等),但是有些安装版的Tomcat下没有catalina.bat,这个时候可以采用如下方法,当然这个方法也是最通用的方法:
打开Tomcat配置,点击Java选项卡,然后将会发现其中有这么两项:Initial memory pool和Maximum memory pool.
Initial memory pool这个就是初始化设置的内存的大小。
Maximum memorypool这个是最大内存的大小
设置完了就按确定,重启服务。
第3章 如何查看内存设置是否生效
3.1 新增tomcat用户
打开tomcat-user.xml文件,增加如下内容
<role rolename="manager"/>
<user username="tomcat" password="123" roles="manager"/>
如图所示:
3.2 查看内存设置是否生效
进入http://localhost:8080/manager/status
用户名:tomcat 密码:123
测试机器,设置的初始化内存为88M,最大内存为188M,设置完成之后,可以看到如下近似数:
(供参考:本机使用apache-tomcat-6.0.29进行测试,如果服务未能install进windows服务,则无法使用用户名、密码登陆,尚未测试出原因)