【问题标题】:In Java is Permanent Generation space garbage collected?在 Java 中是否收集了永久代空间垃圾?
【发布时间】:2011-04-17 07:43:06
【问题描述】:

我已经读到 Perm gen(或 Permanent Generation)空间不是垃圾收集的。但是,在 CMS 集合中,我可以在 GC 日志中看到一些类正在卸载。那么 perm gen 垃圾是在完全收集还是 CMS 收集期间收集的?

【问题讨论】:

  • stackoverflow.com/questions/88235/… 可能重复?无论如何检查该线程它肯定会有所帮助。
  • 不,它根本不重复。这是一个要求是/否答案的概念问题,而不是寻求错误解决方案的问题。

标签: java garbage-collection


【解决方案1】:

PermGen 像堆的其他部分一样被垃圾收集。

这里要注意的是,PermGen 包含类和对象的元数据,即指向分配对象的堆的其余部分的指针。 PermGen 还包含在使用结束时必须手动销毁的类加载器,否则它们会保留在内存中并保持对堆上对象的引用。 Sun / Oracle 博客网站上 Jon Masamitsu 的 "Presenting the Permanent Generation" 文章可能会对您有所帮助。

【讨论】:

  • 已更正。以前是 Sun 博客,所以现在是 Oracle 博客 :)
  • 我已经内联了标题和作者,以便在链接再次断开时人们可以找到它。
  • Permgen 不是堆的一部分
  • 人们总是把原生堆和java堆搞得一团糟。 PermGen 位于 java 进程内的本机堆中。我认为使用堆这个术语有时意味着 Java 和本机堆。
  • PermGen 也有字符串池。
【解决方案2】:

在当前一代 JVM 中,permgen 确实像堆的其他部分一样被收集。 visualgc页面声明它是和老年代一起收集的。

在较旧的 JVM 中,显然并非总是如此。例如,在 Java 5 中,CMS 收集器显然默认不收集 permGen:您可以使用 -XX:+CMSPermGenSweepingEnabled 启用它。我还记得听说过一些非常老的 JVM 根本没有实现 permgen 收集,尽管我找不到可靠的来源... ermm ... "factoid"。

另外一点,很多人错误地将“OutOfMemoryError : permgen”异常归因于 permgen 根本没有被收集。现实是不同的。这些 OOME 的最常见原因是一种隐蔽的存储泄漏,当您将代码热加载到正在执行的 JVM 中时就会出现这种情况。发生泄漏是因为当某个已被替换的旧类的实例仍然可以访问时。这会导致对象的类是可访问的,这会导致类类加载器是可访问的,这会导致旧类的所有以及它们的代码对象、它们的字符串文字和它们的静态帧都是可访问的和静态的。很多这些泄露的对象都存在于 permgen 空间中。


更新

从 Java 8 开始,permgen 不再存在:PermGen elimination in JDK 8

【讨论】:

    猜你喜欢
    • 2011-01-26
    • 1970-01-01
    • 2015-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多