永久空间内存不足 java.lang.OutOfMemoryError: PermGen space

 以下内容,部分是引用了网络,最后部分是经过实验结果:

永久空间内存不足 java.lang.OutOfMemoryError: PermGen space,相比不少使用spring,hibernate等一堆jar包的人都遇到过这个问题,在tomcat reload一个Context多次后,tomcat就挂掉了。
http://www.wujianrong.com/archives/2006/12/javalangoutofmemoryerror_permg.html 
PermGen space这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。
我在做TMS的发布工具的时候,就遇到了问题,这个工具的目的是把一个相同的系统,在tomcat下自动的发布多份,但当卸载,重新发布多次后, tomcat就挂了,整个电脑如同死机一般。后来使用文章里的set JAVA_OPTS=-server -Xms800m -Xmx800m -XX:PermSize=64M-XX:MaxNewSize=256m-XX:MaxPermSize=128m -Djava.awt.headless=true 解决了问题,不过在2G的电脑上,我是把-XX:MaxPermSize=128m 调到了-XX:MaxPermSize=256m。另外我还尝试了把所有的lib都放到tomcat的lib下,一些lib就不能在本项目中再出现了。 
现在看,还是spring,hibernate之类的产生的类导致PermGen space空间不足造成的这些问题。
http://www.javaeye.com/topic/80620?page=1 这个帖子里讨论了这个问题,有人做了些有益的分析可以看看。
我又继续在我的笔记本上做了测试T42,1G内存。tomcat版本6.0.14。
set JAVA_OPTS=-server -Xms256m -Xmx256m -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=256m -Djava.awt.headless=true
这个配置反复发布是可以的,另外又一次测试了将项目下的jar包放到tomcat的lib下的对比。重新安装一个lib下为空的程序是10秒,否则是30秒。

添加的位置就在set JAVA_Opt下面

对于以上两个问题,我的处理是: 

在catalina.bat的第一行增加: 
set JAVA_OPTS=-Xms64m -Xmx256m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m 

在catalina.sh的第一行增加: 
JAVA_OPTS=-Xms64m -Xmx256m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m 

---------------------------------------------------------------------------------------------------------------------------------
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,经常在SUN JDK+Tomcat 5.5.20运行服务的时候遇到这个问题,服务器跑几天后就会挂掉,并报java.lang.OutOfMemoryError: PermGen space异常。
        发现很多人把问题归因于: spring,hibernate,tomcat,因为他们动态产生类,导致JVM中的permanent heap溢出 。然后解决方法众说纷纭,有人说升级 tomcat版本到最新甚至干脆不用tomcat。还有人怀疑spring的问题,在spring论坛上讨论很激烈,因为spring在AOP时使用CBLIB会动态产生很多类。
         但问题是为什么这些王牌的开源会出现同一个问题呢,那么是不是更基础的原因呢?tomcat在Q&A很隐晦的回答了这一点,我们知道这个问题,但这个问题由一个更基础的问题产生。
         于是有人对更基础的JVM做了检查,发现了问题的关键。原来SUN 的JVM把内存分了不同的区,其中一个就是permenter区用来存放用得非常多的类和类描述。本来SUN设计的时候认为这个区域在JVM启动的时候就固定了,但他没有想到现在动态会用得这么广泛。而且这个区域有特殊的垃圾收回机制,现在的问题是permsize默认只有4m,而动态加载类到这个区域后,gc根本没办法回收,最后导致不够用的情况!这种错误常见在web服务器对JSP进行pre compile的时候。

         解决的方法手动设置MaxPermSize大小,修改TOMCAT_HOME/bin/catalina.sh,在“echo "Using CATALINA_BASE:   $CATALINA_BASE"”上面加入以下行:JAVA_OPTS="-server -XX:PermSize=64M -XX:MaxPermSize=128m" ,同时建议将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以达到减少
jar 文档重复占用内存的目的,这是治标的方法,要治本就只能就是不要用SUN的JDK,而改用BEA的JRokit。

        另外若遇到java.lang.OutOfMemoryError: Java heap space 
        Heap size 设置JVM堆的设置是指java程序运行过程中JVM可以调配使用的内存空间的设置.JVM在启动的时候会自动设置Heap size的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)是物理内存的1/4。可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap size 的大小是Young Generation 和Tenured Generaion 之和。提示:在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。提示:Heap Size 最大不要超过可用物理内存的80%,一般的要将-Xms和-Xmx选项设置为相同,而-Xmn为1/4的-Xmx值。 
        解决方法:手动设置Heap size
        修改TOMCAT_HOME/bin/catalina.sh
        在"echo "Using CATALINA_BASE:     $CATALINA_BASE"”上面加入以下行:
        JAVA_OPTS="-server -Xms800m -Xmx800m     -XX:MaxNewSize=256m"

       以下给出1G内存环境下java jvm 的参数设置参考:
JAVA_OPTS="-server -Xms800m -Xmx800m    -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true "

Linux下测试可行的(4G内存)
JAVA_OPTS="-server -Xms2560m -Xmx2560m    -XX:PermSize=256M -XX:MaxNewSize=800m -XX:MaxPermSize=512m -Djava.awt.headless=true "

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值