`
javasogo
  • 浏览: 1774140 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

探究java.lang.OutOfMemoryError: PermGen space

阅读更多

近日,tomcat6下,同时发布多个app(实际上就两个app,这两个app之间通过WebService互相访问,另外有三个Socket服务端监听),系统启动的时候No problem。but系统运行时总是抛出java.lang.OutOfMemoryError: PermGen space。
根据以往经验,调大java的-Xss参数,可是增大至16M时,仍然一如既往的throw Exception。如此,若何?
Google后,得知是因为JVM中的permanent heap溢出。根本原因原来是Java虚拟机的设计问题,SUN 的JVM把内存分了不同的区,其中一个就是permenter区用来存放用得非常多的类和类描述。本来SUN设计的时候认为这个区域在JVM启动的时候就固定了,但他没有想到现在动态会用得这么广泛。而且这个区域有特殊的垃圾收回机制,现在的问题是动态加载类到这个区域后,gc根本没办法回收!(这个问题在spring的论坛上讨论很激烈,因为spring在AOP时使用CBLIB会动态产生很多类。)而且这个bug早在2003年就有人提出了,but Sun好像一直没有解决这个问题呢。
So,没法回收就给它放大!怎么放大呢?
-XX:MaxNewSize=256M -XX:MaxPermSize=256M
另外:PermGen space PermGen space的全称是Permanent Generation space,是指内存的永久保存区域, 这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中, 它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对 PermGen space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen space错误, 这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。
Tomcat下修改此问题:
Windows下,在文件{tomcat_home}/bin/catalina.bat
在文件开头可增加如下设置:
set JAVA_OPTS=-Xms512m -Xmx512m -Xss1024k -XX:MaxNewSize=256M -XX:MaxPermSize=256M
Unix/Linux下,在文件{tomcat_home}/bin/catalina.sh的前面,可增加如下设置:
JAVA_OPTS='-Xms512m -Xmx512m -Xss1024k -XX:MaxNewSize=256M -XX:MaxPermSize=256M'
各参数释义:
-Xms:程序初始化的时候内存栈的大小。
-Xmx:应用程序(不是jvm)能够使用的最大内存数,这个值也不应该设置过大,超过机器内存。否则,tomcat会无法启动。此值可以设置与-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。
-Xss:设置每个线程的堆栈大小。JDK5.0以后每个线程堆栈大小为1M。
-XX:MaxPermSize:设置持久代大小
-XX:NewSize:设置年轻代大小
此处涉及到java虚拟机以及垃圾回收机制的问题,本文不做详细介绍,请直接咨询google。

Eclipse下修改参数的步骤:

Window-->Preference-->Java-->InstalledJREs

选中正在使用中的JRE,单击“Edit”,在“Default VM Argument”中,录入:-Xms256M -Xmx1024M -Xss1024k -XX:MaxPermSize=256M

OK

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics