我在tomcat 5.5和tomcat 6.0服务器上遇到这个奇怪的问题。我有两个将安装在tomcat上的Web应用程序。当tomcat启动时,这两个Web应用程序也会同时启动,但有时一个Web应用程序无法初始化,因为一个应用程序中的init失败,另一个应用程序在运行时遇到classnotfoundexception错误。在tomcat 7.0中,即使其他应用程序无法初始化,应用程序也能正常运行。
经过一些调试后,我发现有一个名为crystal.jar的jar,它位于两个应用程序的web-inf / lib文件夹中。我已经将jar移动到tomcat的common / lib文件夹,然后它开始工作正常。我想知道为什么它在tomcat 7.0中运行正常而不是在tomcat 5.x和tomcat 6.x版本中。这些版本之间的类加载架构是否有任何变化?
由于
EDIT1:该库位于两个应用程序WEB-INF \ lib目录的位置,它们与外部DLLS无关。刚才我读到了tomcat 5.5 classloader架构,并且知道每个Web应用程序都有自己的类加载器。 WEB-INF \ lib文件夹和classes文件夹中的库将加载到此类加载器中。存储在公共目录下的库将被放入共享的类加载器中。然后这个库应该单独加载到Web应用程序的单独的类加载器中。即使一个Web应用程序无法启动,其他Web应用程序也应该独立工作。这就是为什么我感到奇怪并且需要调查更进一步的原因。
答案 0 :(得分:6)
终于找到了这个问题的答案
当库类时,存在已知类型的PermGen内存泄漏 由系统类引用,因此超出其年龄。一 例如,当Java发现JDBC驱动程序或其他一些服务时 并“自动注册”它。它在a中一直引用它 系统,但类本身属于Web应用程序,必须 在应用程序停止时卸载 - 但不能,因为这样 参考。并非所有此类参考文献都易于理解。
在这种情况下的一个典型症状是第一个Web应用程序 依赖于这个系统功能会成功,但第二个和 其他的将失败(因为在注册的服务 系统属于第一个Web应用程序,无法查看类 第二个应用程序的类加载器,反之亦然)。
Tomcat 7和最新版本的Tomcat 6有更好的保护 针对某些已知的PermGen内存泄漏的默认值 配置。
Tomcat 5.5完全没有这种保护。
编辑一些参考资料
http://people.apache.org/~markt/presentations/2010-08-05-Memory-Leaks-JavaOne-60mins.pdf http://people.apache.org/~markt/presentations/2010-11-04-Memory-Leaks-60mins.pdf
http://wiki.apache.org/tomcat/FAQ/Troubleshooting_and_Diagnostics http://wiki.apache.org/tomcat/MemoryLeakProtection