【问题标题】:Java profiling Permgen: how to unload enum inside java classJava分析Permgen:如何在Java类中卸载枚举
【发布时间】:2012-04-08 07:51:57
【问题描述】:

我在服务器 (tomcat) 上重复部署-取消部署相同战争文件的操作导致 PermGen OutOfMemoryError。我的目标是确保在未部署战争时卸载所有类。

这是我的一门课:

public class ClassA {
//static variables & methods
//instance variables & methods

    private EnumInsideClassA myState = EnumInsideClassA.VALUE1;

    private enum EnumInsideClassA
    {
        VALUE1,
        VALUE2
    }
}

当我清除 ClassA 的所有引用时,我看不到 ClassA,并且在取消部署战争时它被卸载。但是,我仍然看到枚举引用并且 ClassA$EnumInsideClassA 没有被卸载。

'myState' 实例变量没有 getter,它只会与 ClassA 一起使用

感谢任何帮助

【问题讨论】:

  • 你试过JVM参数"-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled"吗?这是一个类似的问题:link
  • 感谢您的回复。是的,我有一段时间试过了。我现在又试了一次。但是,内部类(枚举)没有被清理。还有一个原因是 ClassA 在没有这些 JVM 选项的情况下仍然被卸载。

标签: java profiling permgen


【解决方案1】:

但是,我仍然看到枚举引用并且 ClassA$EnumInsideClassA 没有被卸载。

如果您可以看到 enum 引用,您应该能够看到它们的位置。现在将有一些枚举引用可通过枚举类的隐藏静态字段访问,但这些应该是循环引用,不应导致enum 保持可访问。查看其他地方是否有 enum 引用。

【讨论】:

  • 我在 ClassLoader 内的 Vector 中看到了引用。在我的层次结构中,我没有看到任何课程。
  • 引用enum 值?这个怎么可能?为什么类加载器需要知道 enum 值?
  • 嗯.. 据我了解,每个枚举类型都会创建一个对象,并且使用这种类型枚举的所有对象都指向它。如果我错了,请纠正我,但枚举也将被编译为一种类(这意味着它将有一个单独的 .class 文件)。加载枚举的类加载器将有它的定义和对象
  • @Chris - 但enum 在这方面与任何其他类没有本质区别。当您取消部署/重新部署时,对类加载器或类加载器加载的任何类或任何这些类的任何实例的任何可访问引用都将导致永久泄漏。
【解决方案2】:

问题似乎是类加载器没有卸载枚举实例。我有一个测试 servlet 项目,它只有一个枚举。它也不必是私有或内部类枚举,但它确实需要至少被引用一次,以便创建实例。 jvm 似乎没有将枚举视为任何特殊的东西,这似乎是真的。我在静态实例中看到了同样的问题(即自定义类的静态实例在类加载器卸载时没有得到垃圾收集)。

我尝试了各种 -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled,但均未成功。这可能是 JVM 特定的(我在 Mac OS X 上,他们似乎没有这些选项,但 -Xincgc 也不起作用:http://developer.apple.com/library/mac/#documentation/Java/Reference/Java_VMOptionsRef/Articles/JavaVirtualMachineOptions.html)。 stackoverflow上有很多信息,例如Dealing with "java.lang.OutOfMemoryError: PermGen space" error

对于这个特定问题(servlet 重新部署)的最佳解决方案可能是将所有枚举放在一个不需要卸载的 jar 中。

FIY:我的环境是 Mac OS X 10.6.8,Java 1.6.0_31

【讨论】:

    猜你喜欢
    • 2010-11-19
    • 2010-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多