当一个类加载器被释放时,什么时候会在单例上调用?

Ed *_*aub 5 java finalize permgen dynamic-class-loaders java-ee

通过"发布",我的意思是没有对类加载器的引用.

我们遇到了一个问题,即频繁重新部署的Java EE应用程序会占用permgen空间.分析表明,Java EE应用程序中的单例已经传递了对应用程序之外的应用程序类加载器对象的引用(违反Java EE规则),并且在取消部署应用程序时不会清除它们.

假设单例或类对象没有其他引用,那么在释放类的类加载器时是否会调用单例的finalize()? 我想在那里清除流氓入境参考.或者我是在catch-22中,在类加载器本身可以被垃圾收集之前不会调用finalize - 因此由于流氓外部引用而永远不会被调用?

这里的主要问题可能是:

在这种情况下,类对象是否会被垃圾收集? 这可能取决于类加载器行为的规范,或者可能依赖于实现.

参考文献(另一种!;-))将不胜感激,但不是必需的.

Hen*_*ann 4

如果类加载器符合 GC 并且没有其他引用,则具有对其静态引用的类将仅符合垃圾回收的条件。

当且仅当其定义的类加载器可以被垃圾收集器回收时,类或接口才可以被卸载。

http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7

此外,每个类都有对其类加载器的引用。因此,只要存在对类加载器加载的类或来自不可收集对象的这些类的对象的引用,类加载器就没有资格进行 GC。

终结器在对象符合垃圾回收条件之后、实际 GC 发生之前运行一段时间。

在终结器中释放传入引用以防止 GC 的方法不起作用。只要此类引用存在,就不会调用终结器,因为它们会阻止对象获得垃圾回收的资格。例如,您无法从内部破坏此引用链:

singleton instance <--- singleton class <--- class loader <--
<-- any class loaded by that class loader  <-- any object of such a class
<-- object loaded by another classloader referencing such an object or class
Run Code Online (Sandbox Code Playgroud)