Java 随着时间的推移,类定义从jvm中消失(NoClassDefFound)

Java 随着时间的推移,类定义从jvm中消失(NoClassDefFound),java,tomcat,jvm,classloader,permgen,Java,Tomcat,Jvm,Classloader,Permgen,我们这里有一个非常奇怪的问题 jvm:尝试了1.7.0_55-b13和1.7.0_75-b13 雄猫:7.0.56 操作系统:Ubuntu 12.04.5 LTS(64位)(3.5.0-23通用) 在使用spring构建的大型应用程序中使用tomcat 在我们的一个生产环境中,我们有时会得到“NoClassDefFound”,它总是具有相同的堆栈跟踪 它只会在一段时间后发生,并且可以通过特定的工作流进行测试。但是,标记为“not found”的类(在WEB-INF/lib中的一个jar中)已经存

我们这里有一个非常奇怪的问题

jvm:尝试了1.7.0_55-b13和1.7.0_75-b13

雄猫:7.0.56

操作系统:Ubuntu 12.04.5 LTS(64位)(3.5.0-23通用)

在使用spring构建的大型应用程序中使用tomcat

在我们的一个生产环境中,我们有时会得到“NoClassDefFound”,它总是具有相同的堆栈跟踪

它只会在一段时间后发生,并且可以通过特定的工作流进行测试。但是,标记为“not found”的类(在WEB-INF/lib中的一个jar中)已经存在,并且在问题出现和异常开始抛出之前已经被多次使用:上面提到的特定工作流可以在一天中多次成功执行。不知何故,工作流停止工作并开始抛出NoClassDefFound异常

类似乎被加载、使用,然后超时从jvm中消失

jvm使用以下参数运行:

-XX:+UseConcMarkSweepGC 
-Xmx6900m 
-Xms2000m 
-XX:MaxPermSize=900m     
-XX:+UseParNewGC 
-XX:+CMSParallelRemarkEnabled 
-XX:NewRatio=1 
-XX:TargetSurvivorRatio=75 
-XX:SurvivorRatio=8 
-XX:+AggressiveOpts 
-XX:ReservedCodeCacheSize=256m 
-Djava.util.logging.config.file=/var/lib/tomcat7/conf/logging.properties 
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 
-Djava.awt.headless=true 
-Dcom.sun.management.jmxremote=true 
-Dcom.sun.management.jmxremote.port=2037 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=10.71.1.112 
-Dcom.sun.management.jmxremote.password.file=/etc/tomcat7/jmxremote.password 
-Dcom.sun.management.jmxremote.access.file=/etc/tomcat7/jmxremote.access 
-Djava.net.preferIPv4Stack=true 
-Djava.endorsed.dirs=/usr/share/tomcat7/endorsed 
-classpath /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar 
-Dcatalina.base=/var/lib/tomcat7 -Dcatalina.home=/usr/share/tomcat7 
-Djava.io.tmpdir=/tmp/tomcat7-tomcat7-tmp org.apache.catalina.startup.Bootstrap start

有人知道类似的问题吗?

我更正了问题,并在这里发布了解决方案。也许它会在某个时候对某人有所帮助:)

问题并不是我们一开始所想的:类定义并没有从类装入器中消失,但在一开始(启动)并没有初始化

以下是导致错误的工作流:当tomcat上次停止时,它将其会话序列化为一个文件(按照默认会话存储机制)

当应用程序再次启动时,tomcat无法重新加载其会话,因为在初始化类以反序列化其实例时出现了“ExceptionInInitializerError”

然后,对该类的所有后续调用(未正确初始化)生成了我们在问题(NoClassDefFound)中看到的堆栈跟踪

ExceptionInInitializerRor的原因是序列化类试图静态调用spring上下文(当时未初始化的上下文,然后生成了一个NullPointerException,导致ExceptionInInitializer)