意外的GC行为:一些数据总是进入任期生成

noi*_*i.m 8 java garbage-collection

一个非常简单的代码,试图看看垃圾收集器如何运作.

String a = null;
while ( true ) {
  a = new String(" no... ");
}
Run Code Online (Sandbox Code Playgroud)

我正在使用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]
Run Code Online (Sandbox Code Playgroud)

年轻人14880K 因为满满而降下来14872K

这是否意味着8k已经转移到任期一代?我的理解是GC可能被称为某个类'a'的实例,必须被标记为活着并转移到任期一代.这种理解是否正确?还有,这是" 浮动垃圾 "吗?加班任期确实已经填满,需要一个fullGC,但确实需要一段时间.

此外,在这种特殊情况下,并没有收集整个小型收藏品,理想情况下,没有任何东西进入任期一代?所有这些都是短命的物体.

mon*_*ack 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.
Run Code Online (Sandbox Code Playgroud)