Java 永久生成是否总是在HotSpot VM上连续收集?

Java 永久生成是否总是在HotSpot VM上连续收集?,java,garbage-collection,jvm-hotspot,Java,Garbage Collection,Jvm Hotspot,我从阅读中学到了这一点 (…)永久生成当前是按顺序收集的 然而,这篇博文是几年前写的,我想知道垃圾收集算法的最新进展是如何改变这句话的准确性的。我特别想了解新的G1垃圾收集器,它具有: 较旧的垃圾收集器(串行、并行、CMS)都是 分为三部分:年轻一代、老一代和老一代 永久生成固定的内存大小。(...) 在执行垃圾收集时,G1以类似的方式运行 到CMS收集器 但在整个教程中再也没有提到永久性的一代 通过阅读有关CMS的内容——根据上面的陈述,CMS的工作原理与G1类似——我也没有发现任何关于永久世

我从阅读中学到了这一点

(…)永久生成当前是按顺序收集的

然而,这篇博文是几年前写的,我想知道垃圾收集算法的最新进展是如何改变这句话的准确性的。我特别想了解新的G1垃圾收集器,它具有:

较旧的垃圾收集器(串行、并行、CMS)都是 分为三部分:年轻一代、老一代和老一代 永久生成固定的内存大小。(...) 在执行垃圾收集时,G1以类似的方式运行 到CMS收集器

但在整个教程中再也没有提到永久性的一代

通过阅读有关CMS的内容——根据上面的陈述,CMS的工作原理与G1类似——我也没有发现任何关于永久世代的明确信息,但从中了解到

(…)同时标记和扫描根本不紧凑。曾经的对象 无法再分配串行主GC被触发

所以我想知道,现代垃圾收集器,如CMS或G1,是否完全忽略了永久生成,而将其留给完整的GC调用来运行旧的串行GC来清除永久生成(虽然这一系列GC还连续收集年轻和成熟代,但我不认为G1代替CMS是可取的)。我主要感兴趣的是,在STW和收集时间方面,对永久生成执行垃圾收集是否比收集永久生成更昂贵

附加问题:Oracle教程提到永久性生成是堆的一部分。我一直认为永久性生成是在堆之外显式分配的。在最近的热点实现中,这种情况发生了变化吗

感谢您的帮助!

关于让G1能够在没有完整GC的情况下卸载类,有一个很好的方法,但是dependences部分指出,使用[]等待直到永久生成结束,以使JEP156更容易实现是有意义的

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

这是我的理解

编辑:在过去的几天里,我一直在听今年的一些JavaOne课程,非常幸运的是,我今天就找到了一个可以说明一切的课程:

  • 热点当前需要完全GC来收集PermGen
  • 即使在引入元空间之后,这仍然是正确的
  • 最后的总结幻灯片似乎证实了JEP156仍在计划中(但她没有提及)
  • 它甚至回答了一个额外的问题,对此我有一个答案,但没有来源:是的,PermGen在堆中

最新的变化当然是正确的。但是,将某些内容重命名为元空间,并且不限制此空间的大小并不能消除概念上的问题。这个新的元空间仍然需要进行垃圾收集,我猜Oracle将在其上使用与当前在perm gen上使用的相同的算法。这是真的,但它可能会解决这样一个问题,即您必须独立地调整常规堆+永久性堆的大小,并且可能会在其中一个堆上耗尽资源,而另一个堆上仍有一些空间。您可能需要的资源比您拥有的要多,但这个问题可能根本无法解决。感谢有趣的链接。我只是不明白元空间是如何做到这一点的问题消失了。为什么元空间不再需要垃圾收集?今天会发生什么?嗯,也许我不清楚,但这不是我说的。我的意思是Oracle决定在实现JEP156之前等待元空间。所以这意味着它今天仍然是串行的,并且在实现JEP1之前仍将使用Java 856