[讨论] 请教一个Perm out of Memory 的问题。

hahahahah 2012-07-13
    问题描述:在线上服务器上,环境为tomcat-6.0.33,java1.6,部署更新方法为:把最新的class文件覆盖原来的文件,然后在tomcat的管理后台使用stop/start
,但是在进行多次这样的动作后后,产生 Perm out of Memory 异常,然后只能重启tomcat了。项目是struts2+spring3+mybaits。

    用jvisualvm看了之后,发现每次stop/start之后,perm的内存占用就会增加20M左右,多次stop/start之后,就会达到最大值,最终产生Perm out of Memory 异常。

    后来,在测试服务器测试,用的同样的tomcat版本和同样的项目,发现不管怎么stop/start,都不会产生 Perm out of Memory 异常,perm占用内存离最大值还远着呢。perm占用量呈波浪型,应该是有回收了。而在线上服务器上,只增不减。

   
线上服务器相关信息:
  java -version:
java version "1.6.0"
OpenJDK  Runtime Environment (build 1.6.0-b09)
OpenJDK 64-Bit Server VM (build 1.6.0-b09, mixed mode)

tomcat:6.0.33

jconsole看vm摘要:
垃圾收集器: Name = 'PS MarkSweep',
垃圾收集器: Name = 'PS Scavenge',



测试服务器相关信息:
java -version:
java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.8) (rhel-1.22.1.9.8.el5_6-i386)
OpenJDK Client VM (build 19.0-b09, mixed mode)

tomcat:6.0.33

jconsole看vm摘要:
垃圾收集器: Name = 'Copy',
垃圾收集器: Name = 'MarkSweepCompact'


其实,这个问题也不算太严重,毕竟多次部署之后重启一下tomcat也没多大关系。本着深究到底的原则,一定要搞清楚问题的本质。大量google之后还是没有头绪,这里高手多,希望能给一些指导性的意见。谢谢。。。
ol_beta 2012-07-15
LZ 启动jvm的参数是啥?方便的话可以贴出来。
一般情况下hotspot应该是不收集PermGen的,但是可以在特定的收集器下进行收集。
# java -XX:+PrintFlagsFinal | grep -i "unload"
     bool CMSClassUnloadingEnabled                  = false           {product}
    uintx CMSClassUnloadingMaxInterval              = 0               {product}
     bool ClassUnloading                            = true            {product}
     bool ExplicitGCInvokesConcurrentAndUnloadsClasses  = false           {product}
     bool TraceClassUnloading                       = false           {product rw}

如果用的是CMS 可以指定CMSClassUnloadingEnabled来收集PermGen。
另外ClassUnloading这个参数默认应该是true 不知到你有没有设置这个。
hahahahah 2012-07-16
没有自己设置gc策略,都是jvm自动选择的。

-server -Xms64m -Xmx1024m -XX:PermSize=64m -XX:MaxPermSize=256m -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -Xloggc:/data/logs_8080/gc.log

另外,你说的方法指定CMS, ClassUnloading为true,我试过,但没有效果。。每次tomcat后台stop/start都会增加20M左右,只增不减。。。。直到out of memory为止。。。。
chong_zh 2012-07-18
会不会是tomcat work目录缓存没有清,又载入了新版本class的缘故
ol_beta 2012-07-20
hahahahah 写道
没有自己设置gc策略,都是jvm自动选择的。

-server -Xms64m -Xmx1024m -XX:PermSize=64m -XX:MaxPermSize=256m -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -Xloggc:/data/logs_8080/gc.log

另外,你说的方法指定CMS, ClassUnloading为true,我试过,但没有效果。。每次tomcat后台stop/start都会增加20M左右,只增不减。。。。直到out of memory为止。。。。

应该不是JVM的问题
tomcat stop是你们自写的脚本? 正常关闭是shutdown。看看stop pid是否有变化,或者kill掉再重启。
hahahahah 2012-07-26
ol_beta 写道
hahahahah 写道
没有自己设置gc策略,都是jvm自动选择的。

-server -Xms64m -Xmx1024m -XX:PermSize=64m -XX:MaxPermSize=256m -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -Xloggc:/data/logs_8080/gc.log

另外,你说的方法指定CMS, ClassUnloading为true,我试过,但没有效果。。每次tomcat后台stop/start都会增加20M左右,只增不减。。。。直到out of memory为止。。。。

应该不是JVM的问题
tomcat stop是你们自写的脚本? 正常关闭是shutdown。看看stop pid是否有变化,或者kill掉再重启。


兄弟,理解错了,不是stop tomcat,是tomcat的管理后台,start/stop项目。

pid肯定没变化啊。就是不想stop或者kill掉整个tomcat。想通过后台管理项目的更新部署,才会出现这个问题。
hahahahah 2012-07-26
看了很多资料,包括:

http://code.alibabatech.com/blog/experience_530/tomcat-7-will-address-web-application-reload-caused-outofmemoryerror-oome-problem-3.html

除了换jvm,这个问题在tomcat6下应该是没法解决了。。
xiaoZ5919 2012-08-13
呵呵 用的reload吧! 如楼上众兄弟所说sun的jvm默认不对持久代回收,tomcat的reload机制是干掉原来的webclassloader,这重新起一个并重新加载一遍所有的jar,如你引用的jar过多的话这时候还用另外一个问题容易出现open too man files
wangdf_jee 2012-08-13
我在工作中也碰到这种问题
1.stop
2.替换
3.start
或者
增大-XX:MaxPermSize
都可以解决此类问题.


你碰到的问题
把PermSize和MaxPermSize的值设为相同,
我想也可以解决你的问题

wangdf_jee 2012-08-13
线上和你测试机被加载的class和jsp数量不一样
Global site tag (gtag.js) - Google Analytics