[讨论] 奇怪的System.gc()

richard_2010 2011-07-23

代码很简单:

public class GCTest {
	public static  void main(String[] args) {
		GCTest gcTest = new GCTest();
		System.gc();
		
	}

}



运行参数:java -Xms30m -Xmx30m -Xmn10m -XX:+PrintGCDetails GCTest

GC日志:
[Full GC (System) [Tenured: 0K->134K(20480K), 0.3246722 secs] 327K->134K(29696K)
, [Perm : 361K->361K(12288K)], 0.3255925 secs] [Times: user=0.01 sys=0.00, real=
0.33 secs]
Heap
def new generation   total 9216K, used 163K [0x25d10000, 0x26710000, 0x26710000
)
  eden space 8192K,   2% used [0x25d10000, 0x25d38fc8, 0x26510000)
  from space 1024K,   0% used [0x26510000, 0x26510000, 0x26610000)
  to   space 1024K,   0% used [0x26610000, 0x26610000, 0x26710000)
tenured generation   total 20480K, used 134K [0x26710000, 0x27b10000, 0x27b1000
0)
   the space 20480K,   0% used [0x26710000, 0x267319b8, 0x26731a00, 0x27b10000)
compacting perm gen  total 12288K, used 361K [0x27b10000, 0x28710000, 0x2bb1000
0)
   the space 12288K,   2% used [0x27b10000, 0x27b6a7a0, 0x27b6a800, 0x28710000)
    ro space 8192K,  67% used [0x2bb10000, 0x2c072f30, 0x2c073000, 0x2c310000)
    rw space 12288K,  53% used [0x2c310000, 0x2c980180, 0x2c980200, 0x2cf10000)
-----------------------------------------------

问题是为什么垃圾回收器运行后,新生代里面存活的对象直接竞升到旧生代里去了?-client模式。

 

richard_2010 2011-07-23
撒迦帮忙看下啊。。。

RednaxelaFX编辑:我还在机场等飞机…本上没client VM来重现你说的状况所以暂时帮不上忙。明天吧…
richard_2010 2011-07-27
撒迦还没回来?明天还得上课吧?
RednaxelaFX 2011-07-27
richard_2010 写道
问题是为什么垃圾回收器运行后,新生代里面存活的对象直接竞升到旧生代里去了?-client模式。

嗯,一开始没看清楚你的问题。刚看了一下觉得挺简单的。

HotSpot的GC除了G1之外默认在System.gc()的时候是做全堆收集的。G1我还没仔细看所以这里不评论。
在做完全堆收集后,young gen默认是要[尽量]清空的,所以执行System.gc()时在young gen里活着的对象都会直接晋升。HotSpot里的这些GC实现就这么设计的。对象的“年龄”是在做young GC的时候才会被考虑。

是不是分代式GC就一定要这样呢?不一定,没这种强制的规定。
甚至对象的“年龄”是不是一定要用“经历young GC的次数”来定义也不一定,虽然HotSpot采用这样的定义,但在别的地方也存在别的实现。
richard_2010 2011-07-27
原来还有一个“尽量”清空的原则。。。我懂了

甚至对象的“年龄”是不是一定要用“经历young GC的次数”来定义也不一定
---------------------
恩。这个倒听说过。
谢谢啦。
Global site tag (gtag.js) - Google Analytics