[讨论] 请教一个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数量不一样
|