HotSpot虚拟机中的永久代是否总是串行收集?

9

从阅读一篇相当成熟的Oracle博客文章中,我了解到:

(...) 永久代目前是串行收集的。

然而,这篇博客文章是几年前的,我想知道垃圾回收算法的最新进展如何改变了这个说法的准确性。我特别想知道新的G1垃圾收集器,它被Oracle描述为:

旧的垃圾收集器(串行、并行、CMS)都将堆结构化为三个部分:固定内存大小的年轻代、老年代和永久代。(...)在执行垃圾收集时,G1的操作方式类似于CMS收集器。

但整个教程中从未提到过永久代。

阅读有关CMS的内容-根据上述声明,它的工作方式类似于G1-我没有找到有关永久代的明确信息,但从这篇其他博客文章中了解到:
(...)并发标记和清除根本不压缩。一旦对象不能再分配,就会触发串行主GC。
因此,我想知道现代垃圾收集器(如CMS或G1)是否完全忽略了永久代,并将其留给full GC调用来清理永久代(而此串行GC也按顺序收集年轻代和成熟代,我认为如果使用CMS而不是G1,则不应该这样做)。我主要想知道在STW和收集时间方面,对永久代进行垃圾回收是否比对老年代进行垃圾回收更昂贵。 奖励问题:Oracle教程提到永久代是堆的一部分。我一直认为永久代是在堆之外显式分配的。这在最近的HotSpot实现中有所改变吗?
谢谢您的帮助!

4
最近的变化是在Java 8中不再有永久代(permgen)了。 - zapl
当然,这是正确的。然而,将某些东西重命名为元空间并不限制此空间的大小,并不能消除概念上的问题。这个新的元空间仍然需要进行垃圾回收,我猜Oracle会使用与当前在perm gen上使用的相同算法。 - Rafael Winterhalter
这是正确的,但它可能会消除您必须独立调整常规堆和PermGen大小并且在其中一个上用尽资源而另一个仍有一些空间的问题。您可能需要比您拥有的更多的问题可能根本无法解决。 - zapl
1个回答

3

有一个JEP156关于使G1能够在没有完整GC的情况下卸载类,但是依赖部分指出,等到永久代消失之后[JEP122]才有意义,以使JEP156更容易实现。

因此,看起来这个问题确实可以在Java 8中解决,但不仅仅是由于元空间,而是因为元空间被视为对类进行增量GC的先决条件。

这就是我的理解。

编辑:在过去的几天里,我一直在听今年的JavaOne会议,并且非常幸运地发现了一个关于PermGen removal的话题,它概括了所有内容:

  • HotSpot目前需要完整GC来收集PermGen
  • 即使引入Metaspace,这仍然是真的
  • 最后的总结幻灯片似乎证实了JEP156仍在计划中(但她没有谈论它)
  • 它甚至回答了我有答案但没有来源的额外问题:是的,PermGen在堆中

谢谢提供有趣的链接。我只是不明白元空间如何解决这个问题。为什么元空间不再需要进行垃圾回收?现在会发生什么情况? - Rafael Winterhalter
1
嗯,也许我没有表达清楚,但这不是我说的。我的意思是Oracle决定在实施JEP156之前等待metaspace。因此,这意味着直到今天它仍然是串行的,并且在Java 8中仍将是如此,直到他们实施JEP156。 - Djizeus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接