Java主要和次要垃圾收集

25

我一直在学习Java中的垃圾回收(Garbage Collection),并阅读了SO Q&A,但是我对垃圾回收的类型感到困惑。

以吞吐量收集器(Throughput Collector)为例(又称并行收集器),文档中说它使用多个线程进行Minor收集,单个线程进行Major收集(与串行收集器相同)。

现在我的问题是:

  1. Full GC是什么意思:a)它是否意味着同时执行了Minor和Major收集?还是b)Full GC == Major Collections?哪一个是正确的?
  2. 如果是a),那么Minor Collection是否仍然使用多个线程,而Major Collection则只使用单个线程?
  3. 如果是b),那么是不是Young Generation和Old Generation都是使用单个线程清除?

另外,

4. Full GC只影响OldGeneration还是也会影响YoungGeneration?

提前致谢。


2
+1。感谢您提出我的问题。 - Imposter
2个回答

39

让我解释一下。

以吞吐量收集器(也称并行收集器)为例。文档中提到它使用多个线程执行小型垃圾收集,只使用单个线程进行大型垃圾收集(与串行收集器相同)。

我们需要了解的是,在大多数新系统上,默认情况下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(如果老年代已满,则可以更改顺序以首先释放Older Generation,以便它可以从Young Generation接收对象)。

好了,回到重点。JVM将老年代(或Perm)中的Major Collection视为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]
  • 表示进行的是Minor GC,使用多线程进行Young Generation垃圾回收。
  • 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]
  • 表示进行的是Major GC,使用单线程进行Old Generation垃圾回收。如果都用多线程,则称为Parallel GC。

4
HotSpot 6和7中也有-XX:+UseG1GC选项,它能够同时管理新生代和老年代。 - Frank Pavageau
我需要澄清一下,Major GC 也会收集永久代吗?还是只有 Full GC 才会这样做? - amarnath harish

-1

虽然Goblin的回答在很大程度上仍然正确,但至少其中一部分现在已经过时:

这要看情况。JVM将每个Major Collection报告为Full GC。

CMS和G1都区分新生代(minor)收集、旧生代的并发收集和Full GC。后者是一种最后的备选方案,大部分GC应该由新生代和并发收集来处理。


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