24

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

我们以吞吐量收集器为例。(又名并行收集器)。文档说它使用多个线程来执行次要集合和主要集合的单线程(与串行收集器相同)。

现在我的问题:

  1. Full GC 是什么意思: a) 这是否意味着 Minor 和 Major 收集都已完成?或者 b) Full GC == Major Collections?哪一个?
  2. 如果 a),这是否意味着 Minor Collection 仍然使用多个线程完成,而 Major 使用 Single 完成?
  3. 如果 b),这是否意味着年轻代和老年代都使用单线程清除?

另外,4. Full GC 是否也只影响 OldGeneration 或 YoungGeneration?

提前致谢。

4

2 回答 2

38

让我解释。

我们以吞吐量收集器为例。(又名并行收集器)。文档说它使用多个线程来执行次要集合和主要集合的单线程(与串行收集器相同)。

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

当 JVM 无法为新对象分配空间时触发 Minor Collection(请记住:新对象总是分配在年轻一代的伊甸园区域)。

下一个问题:

Full GC 是什么意思: a) 这是否意味着 Minor 和 Major 收集都已完成?或者 b) Full GC == Major Collections?哪一个?

和,

另外,4. Full GC 是否也只影响 OldGeneration 或 YoungGeneration?

这取决于。JVM 将每个 Major Collection 报告为 Full GC。[尝试使用这些标志java -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamp]。迂腐的定义是 Full GC 首先运行 Minor,然后是 Major(尽管如果老年代已满,则可以切换顺序,在这种情况下,它首先被释放以允许它从年轻代接收对象)。

好,回到正题。JVM 将 Major Collection [in the Older (or Perm) Generation] 视为 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 完成?

是的。请参阅我的答案的开头。年轻代和老一代由不同的收集器提供服务。对于年轻代,您可以使用以下任何一种:

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

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

  • -XX:+UseParallelOldGC
  • -XX:+UseConcMarkSweepGC
于 2013-05-14T22:23:47.443 回答
-1

虽然哥布林的回答在广义上仍然是正确的,但至少这部分现在已经过时了:

这取决于。JVM 将每个 Major Collection 报告为 Full GC。

CMS 和 G1 都区分新生代(次要)收集、老年代的并发收集和完整 gcs。后者是不得已而为之的事情,大部分 GC 应该由新一代和并发集合处理。

于 2017-08-01T21:14:19.423 回答