7

我在使用 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 类加载器架构的信息,并了解到每个 Web 应用程序都有自己的类加载器。WEB-INF\lib 文件夹和 classes 文件夹中的库将被加载到这个类加载器中。存储在公共目录下的库将被放置到共享类加载器中。然后这个库应该在 web 应用程序的单独类加载器中单独加载。即使一个 Web 应用程序无法启动,其他 Web 应用程序也应该独立工作。这就是为什么我觉得奇怪,需要进一步调查。

4

1 回答 1

6

终于找到了这个问题的答案

存在一种已知的 PermGen 内存泄漏,当库类被系统类引用并因此超出其使用期限时。一个例子是当 Java 发现 JDBC 驱动程序或其他一些服务并“自动注册”它时。它在系统中保持对它的引用,但该类本身属于 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://eclipse.org/mat/

http://wiki.apache.org/tomcat/FAQ/Troubleshooting_and_Diagnostics http://wiki.apache.org/tomcat/MemoryLeakProtection

于 2012-06-10T19:20:53.960 回答