【问题标题】:OSGI with Custom Class Loader Perm Gen IssueOSGI 与自定义类加载器 Perm Gen 问题
【发布时间】:2017-11-04 15:02:21
【问题描述】:

出于我们的目的,我们没有使用将 jar 构建到包中的标准 OSGI jar 参考。对于在线升级,我们希望能够在升级期间提供新的和更新的 jar。在启动和停止包的 Activator 类中,我们实现自己的 URLClassLoader,然后在子文件夹中查找所有 jar,并将 OSGI CLassLoader 作为父级提供给 URLClassLoader。这很棒,因为现在应用程序的管理员可以简单地将 jar 添加到类路径并重新启动应用程序(osgi 重新启动,而不是实际关闭 jvm)。我们做得很好。此外,我们的 bundle.jar 不会随着时间的推移变得很大,因为所有 jar 引用都不包含在 bundle jar 中。

但是,现在我们可以使用 OSGI 在同一个 JVM 中远程重启应用程序。但是,当重新启动时,我们添加的类加载器永远不会被垃圾收集。因此,如果您重新启动应用程序 10 次,那么它将导致 Perm Gen 内存不足(Java 1.7)。

我们试图模仿 apache WebAppClassLoader 在卸载时所做的事情,但这也没有删除引用。

我已经在互联网上搜索了解决方案,并承认我们在典型的 OSGI 实现之外进行编码,但是没有办法清除对 ClassLoader 的引用。重新启动后,老实说不应该有任何引用。

我们使用 MAT 来分析堆转储,但引用的类列表总是不同的。

有谁知道加载外部库的更好方法,以便在 OSGI 中使用?

感谢您提供任何信息!

【问题讨论】:

  • 所以我们尝试使用 URLClassloader 删除,完全依靠 OSGI 来管理类加载。然后我们通过多次启动和停止包来测试这一点,现在,BundleWiringImpl$BundleClassLoaderJava5 仍然显示每次我们启动和停止包时的引用,而不是 URLClassloader 引用所有类。
  • 一个类加载器只有在它的所有类都不可达的情况下才能进行垃圾回收,这意味着这些类的所有实例也是不可达的。如果你有泄漏,没关系,你如何改变类加载器结构,你只能通过识别泄漏并修复它来摆脱它。

标签: osgi classloader


【解决方案1】:

使用 Java 8,版本 8 中没有永久代。

【讨论】:

  • 我们在 Java 8 中遇到了同样的问题。由于元空间是在 Java 8 中的堆中定义的,因此需要更长的时间来产生内存不足。
猜你喜欢
  • 2023-03-07
  • 2013-05-15
  • 2011-12-05
  • 2012-03-24
  • 1970-01-01
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多