停止我的网络应用程序后,大量的PermGen没有被释放。罪魁祸首似乎是WebappClassLoader(在Tomcat中,但它也发生在Jetty中),它通过来自一堆其他对象的引用保存在内存中。下图显示了引用WebappClassLoader的对象以及引用它们的内容,等等。
其中一个粘性对象似乎是net.lag.logging.Level$INFO$
的一个实例,引用存储在known
的静态java.util.logging.Level
数组中。
java.util.logging.Level
似乎保留了对其自身所有实例的静态引用。糟糕,讨厌的java.util.logging.Level
!我可以做些什么吗? java.util.logging框架由第三方库使用,所以我认为我没有选择不使用它。
答案 0 :(得分:2)
如果没有让Sun修复Level实现或更改库以取消其自定义Level,我能想到的唯一方法是将库移出Web应用程序类加载器并进入容器(共享或通用类加载器)
如果这样做,仍会有Level的自定义实例,但它们将不再链接到Web应用程序。因此,如果您退回webapp,它将继续回收相同级别(不会泄漏新级别)。
当然,这会影响库的类加载器,并且可能会中断。有些东西需要在Web应用程序中,不能移动到容器中。即使库继续工作,它本身也可以保持对Web应用程序的其他部分的类似引用,这将再次成为完全相同的问题。不过,试一试。