8

运行一个非常简单的代码来尝试查看垃圾收集器的功能。

String a = null;
while ( true ) {
  a = new String(" no... ");
}

我正在使用 ParallelGC。我打印了 GC 结果,这是第一个(次要)GC。

[GC [PSYoungGen: 16448K->1616K(19136K)] 16448K->1624K(62848K), 0.0022134 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

youngGen 下降了14880K 但是 fullHeap 下降了14872K

这是否意味着 8k 已经转移到终身制?我的理解是 GC 可能被称为“a”类的某些实例,必须被标记为活动并移至终身代。这种理解正确吗?还有,这是“漂浮垃圾”吗?随着时间的推移,任期代确实会被填满,并且需要 fullGC,但这确实需要一段时间。

另外,在这种特殊情况下,不应该收集整个次要集合,理想情况下没有任何东西进入任期代吗?所有这些都是短暂的物体。

4

2 回答 2

2

当 GC 正在进行时,您有 1 个 String 实例(while 循环内的强引用),因此一个是存活的,因此是 8k。

在这种情况下,我不会调用 String ref 浮动垃圾。浮动垃圾是指当 GC 检查对象时对象尚未准备好进行 GC,但在 GC 完成时已准备好。一个例子就是。

Thread1:    Person p = new Person("sammy")

    Thread2:    gc runs and sees that the Person instance is reachable through p.

Thread1:    p = null; // This Person instance is now unreachable.

    Thread2:    GC finishes. The person instance could have been collected but was reachable at the time the collector checked it.
于 2013-07-15T06:28:55.877 回答
0

我不认为你的测量是准确的。

首先,当 GC 发生时,伊甸园被擦除,幸存的对象进入幸存者空间。所以在你的情况下,这解释了为什么 YoungGen 从 16448K 变为 1616K :那些 1616K 是幸存者的占用。

同时,GC后的总堆占用为1624K,也就是说老年代确实有8K的数据。

术语“浮动垃圾”是指 CMS 收集,其中新死的对象不会被收集器捕获。它不适用于 ParallelGC。

至于您的测试用例,字符串对象永远不会进入老一代。它们最多会存活 1 个 GC 周期并进入一个 Survivor 空间,然后将被回收

希望有帮助!

于 2013-07-15T12:51:02.720 回答