当前位置: 首页 > 面试题库 >

什么时候以及如何将Java类加载器标记为垃圾回收?

淳于亦
2023-03-14
问题内容

我们正在创建多个子类加载器,以将多个子应用程序加载到Java应用程序“容器”中,从而对热部署进行原型设计。当特定类加载器的类路径发生更改时(即,添加,删除,更新了jar),旧的类加载器将被丢弃(未引用),并为jar的新类路径创建新的类加载器。

更新类路径后,触发热部署,我们进行了堆转储。堆转储(使用内存分析器)表明旧的类加载器未在进行垃圾回收。父类加载器中的某些类正在缓存旧的类加载器。调用了以下操作来清除这些缓存:

java.lang.ResourceBundle.clearCache(classLoader);
org.apache.commons.logging.LogFactory.release(classLoader);
java.beans.Introspector.flushCaches();

即使清除了上面的缓存,旧的类加载器仍然没有被垃圾回收。对类加载器的其余引用包括以下内容:

  • 类加载器加载的类
  • java.lang.Package由类加载器本身创建
  • 由类加载器本身创建的java.lang.ProtectionDomain

以上所有内容都是类加载器中的循环引用,应触发垃圾回收。我不确定为什么不是这样。有人知道为什么即使使用循环引用仍旧不对旧的类加载器进行垃圾回收吗?


问题答案:

我一直听说Classloader卸货是有问题的。从理论上讲,它们是在不引用对象实例且不需要类卸载时进行垃圾收集的,但实际上似乎存在更多问题。细微的引用可能会泄漏并阻止对其Classloader进行回收。在应用程序服务器中,经过无数次重新部署周期后,有时我得到了OutOfMemoryError: PermGen space

这么说,我想在某处有一个讨厌的引用阻止了它的收集-内存分析器可能未正确遵循链接。似乎所有这些事情都可能发生,如这些文章中所述:

  • 类加载器泄漏:可怕的PermGen空间异常
  • 如何修复可怕的PermGen空间异常

另外,我也不知道您在做什么,但是如果您可以等待JDK
7,则可以查看一下AnonymousClassLoader。将介绍它们以更好地支持动态语言,如本博文所述:

  • InvokeDynamic的初衷

希望对您有帮助。



 类似资料:
  • 问题内容: 在这个主题中,我问了一个有关Java垃圾收集的问题。但是我得到的答案又给了我一个问题。 有人提到垃圾回收器也可以收集类。这是真的? 如果是真的,这是如何工作的? 问题答案: 没有任何引用时,可以对Java中的类进行垃圾回收。在大多数简单的设置中,这永远不会发生,但是在某些情况下可能会发生。 有很多方法可以使类可达,从而阻止其符合GC的资格: 该类对象仍然可以访问。 表示类的对象仍然可以

  • 问题内容: 是什么决定了垃圾收集器何时真正收集?它是在一定时间之后还是在一定数量的内存用完之后发生的吗?还是还有其他因素? 问题答案: 它在确定是时候运行时运行。在世代垃圾收集器中,一种常见的策略是在第0代内存分配失败时运行收集器。也就是说,每次你分配一小块内存(大块通常直接放置在“旧”代中)时,系统都会检查gen-0堆中是否有足够的可用空间,如果没有,则运行GC释放空间以使分配成功。然后将旧数据

  • 问题内容: 据我所知,GC仅在JVM需要更多内存时才使用,但我不确定。所以,请有人提出这个问题的答案。 问题答案: 据我了解,Java的垃圾收集算法非常复杂,而且不那么直接。另外,GC可用的算法还不止这些,可以在VM启动时通过传递给JVM的参数进行选择。 这里有一个有关垃圾收集的常见问题解答:http : //www.oracle.com/technetwork/java/faq-140837.h

  • 问题内容: 我对可以控制CMS收集器启动时间的两个参数感到困惑: (默认为70%) (默认情况下超过90%) 这些参数的确切含义是什么?收集器什么时候开始(标记阶段)并收集(清扫阶段)? 问题答案: 决定何时启动CMS(为了使此选项生效,您还必须设置)。是确定世代空间大小的选项。 参见例如… http://java.sun.com/docs/hotspot/gc1.4.2/faq.html 通常无

  • 问题内容: 什么是JavaScript垃圾回收?为了编写更好的代码,对于Web程序员来说,了解JavaScript垃圾回收有什么重要意义? 问题答案: 从该页面引用: JScript使用了非世代的标记清除垃圾收集器。它是这样的: 每个“范围内”的变量都称为“清除剂”。清道夫可以指数字,对象,字符串等。我们维护一个清道夫列表- 变量进入作用域时将移入scav列表,超出范围时将其移出scav列表。 垃

  • 所以我有点理解java类加载器是什么,因为它为JVM准备编译的.class文件。我几乎不理解它是如何工作的,因为它试图通过一系列递归调用父类加载器的步骤来加载一个类。我没有理解的是类加载器是如何确定的。也就是说,如何为类选择类加载器? 我现在问这个问题是因为我基本上遇到了以下问题:我无法将子类强制转换到实现的接口。 该类如下所示: 这是我的(略经编辑的)stacktraces的结尾: 这里,Acc