6

我们正在用 Scala 编写一个带有很多类的大型 GUI 应用程序,我们不得不增加 PermGen 空间才能加载所有类。该应用程序本身显示了一系列基于屏幕的活动,每个活动都加载自己的大量类。在任何时间点都只加载/显示一个活动。在经历了一些活动之后,我们OutOfMemoryError在 PermGen 空间有了一个。

我知道 PermGen 空间就像堆的其余部分一样被垃圾收集,但我很想看看我是否可以通过每个活动一个来减少所需的 PermGen 空间,ClassLoader以便允许类卸载。

所以:

  1. 我知道系统 ClassLoader 加载的类无法卸载,因为它们的类加载器将永远引用它们。真的吗?
  2. 如果我的自定义类加载器加载的类的实例不再存在,并且类加载器可以被垃圾收集,它的类是否会被卸载,从而释放 PermGen 空间?
  3. 是否有任何关于(或会阻止)类卸载的警告?
4

1 回答 1

6

...如果我可以通过为每个活动设置一个 ClassLoader 来减少所需的 PermGen 空间,以便允许卸载类。

是的,类有资格被卸载的唯一方法是使用的类加载器是垃圾收集的。这意味着对每个类和类加载器本身的引用必须为零。

你的 PermGen 有多大?你可能会逃脱与 PermGen 的碰撞:

-XX:MaxPermGen=256m

在你的命令行上。将其设置为 512m 并不少见。如果您想要一个真正强大的解决方案,您将需要使用每个“活动”的自定义类加载器。为了帮助调试,请在命令行中添加以下自解释参数:

-XX:+TraceClassLoading

这将打印出类,因为它们在 JVM 中加载到命令行。

于 2011-10-14T17:00:52.463 回答