Java主要和次要垃圾收集

我一直在阅读Java中的垃圾收集和SO Q&A,但我对垃圾收集的类型感到困惑。

我们以吞吐量收集器为例。 (又名并行收集器)。 文档称它使用多个线程来执行Minor集合,并使用单个线程来处理Major集合(与Serial collector相同)。

现在我的问题:

  1. 全GC的含义是什么:a)是否意味着小型和主要collections品都已完成? 或者b)完整GC ==主要collections? 哪一个?
  2. 如果a),是否意味着Minor Collection仍然使用多个线程完成,而Major是使用Single完成的?
  3. 如果b),是否意味着使用单线程清除了Young和Old Generations?

另外,4。Full GC是否仅影响OldGeneration或YoungGeneration?

提前致谢。

让我解释。

我们以吞吐量收集器为例。 (又名并行收集器)。 文档称它使用多个线程来执行Minor集合,并使用单个线程来处理Major集合(与Serial collector相同)。

这是有待理解的。 默认情况下,在大多数较新的系统上,JVM使用两种不同的垃圾收集器用于年轻和老一代。 在我的机器上:我有年轻一代的并行新收集器 老一代的并发标记和扫描收集器

当JVM无法为新对象分配空间时,会触发次要集合(请记住:新对象始终在Young Generation的Eden区域中分配)。

下一个问题:

全GC的含义是什么:a)是否意味着小型和主要collections品都已完成? 或者b)完整GC ==主要collections? 哪一个?

和,

另外,4。Full GC是否仅影响OldGeneration或YoungGeneration?

这取决于。 JVM将每个主要集合报告为完整GC。 [尝试使用这些标志java -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamp ]。 迂腐的定义是Full GC先运行Minor,然后是Major(虽然如果旧生成已满,可以切换顺序,在这种情况下,它首先被释放以允许它接收来自Young Generation的对象)。

好的,回到原点。 JVM认为Major Collection [在较旧(或Perm)生成中)为Full GC。 下面是我能够快速编写的程序的输出来说明这一点。 第一行是Minor GC,第二行是Major(Full)GC。 你可以看到它只发生在老一代(CMS)中,并且能够将老一代从1082K减少到1034K。

  • 11.431: [GC 11.431: [ParNew: 1152K->128K(1152K), 0.0009893 secs] 2111K->1210K(6464K), 0.0010182 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
  • 17.882: [Full GC (System) 17.882: [CMS: 1082K->1034K(5312K), 0.0212614 secs] 2034K->1034K(6464K), [CMS Perm : 9426K->9410K(21248K)], 0.0213200 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]

下一个问题:

如果a),是否意味着Minor Collection仍然使用多个线程完成,而Major是使用Single完成的?

是。 看到我的答案的开头。 年轻和年长的世代由不同的collections家服务。 对于Young Generation,您可以使用以下任何一种方法:

  • -XX:+UseSerialGC
  • -XX:+UseParallelGC
  • -XX:+UseParNewGC

对于老一代,可用的选择是:

  • -XX:+UseParallelOldGC
  • -XX:+UseConcMarkSweepGC

虽然精灵的答案仍然是正确的,但至少这一部分现在已经过时了:

这取决于。 JVM将每个主要集合报告为完整GC。

CMS和G1都区分新一代(次要)集合,旧一代和全集合的并发集合。 后者是最后的事情,大多数GCing应该由新的和并发集合处理。