使用一个非常简单的代码来尝试查看垃圾收集器的功能。
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]
年轻人来自14880K
但是,只有14872K
这是否意味着8k已经转移到任期一代?我的理解是GC可能被称为某个类'a'的实例,必须被标记为活着并转移到任期一代。这种理解是否正确?还有,这是“Floating Garbage”吗?加班任期确实已经填满,需要一个fullGC,但确实需要一段时间。
此外,在这种特殊情况下,并不是整个小型收藏品都被收集起来,理想情况下,没有任何东西进入任期一代?所有这些都是短命的物体。
答案 0 :(得分: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.
答案 1 :(得分:0)
我认为您的测量结果并不准确。
首先,当GC发生时,Eden被擦除,幸存的物体进入Survivor空间。所以在你的情况下,这解释了为什么YoungGen从16448K变为1616K:那些1616K是幸存者的入住。
同时,GC之后的总堆占用率为1624K,这意味着老一代确实包含8K数据。
术语“浮动垃圾”是指CMS集合,其中新收集的对象不会被收集器捕获。它不适用于ParallelGC。
对于您的测试用例,String对象永远不会进入Old Generation。它们最多可以在1个GC循环中存活并进入幸存者空间,然后将被回收
希望有所帮助!