日期:2014-05-19  浏览次数:20618 次

JVM中Minor GC触发结果不明白
代码如下:
public static void main(String[] args) throws InterruptedException {
Thread.sleep(10000);
List<DataObject> objects = new ArrayList<DataObject>();
for(int i=0;i<23285; i++)
{
objects.add(new DataObject(1));
}
objects.size();
objects = null;
Thread.sleep(3000);

}
class DataObject{
byte[] bytes = null;
public DataObject(int factor){
bytes = new byte[factor * 1024];
}
}

运行参数如下:
-Xms150M -Xmx150M -Xmn30M -XX:+UseSerialGC
运行结果:用jstat观察
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
3072.0 3072.0 0.0 0.0 24576.0 491.5 122880.0 0.0 12288.0 372.4 0 0.000 0 0.000 0.000
3072.0 3072.0 0.0 0.0 24576.0 491.5 122880.0 0.0 12288.0 372.4 0 0.000 0 0.000 0.000
3072.0 3072.0 0.0 0.0 24576.0 491.5 122880.0 0.0 12288.0 372.4 0 0.000 0 0.000 0.000
3072.0 3072.0 0.0 0.0 24576.0 491.5 122880.0 0.0 12288.0 372.4 0 0.000 0 0.000 0.000
3072.0 3072.0 0.0 0.0 24576.0 491.5 122880.0 0.0 12288.0 372.4 0 0.000 0 0.000 0.000
3072.0 3072.0 0.0 0.0 24576.0 491.5 122880.0 0.0 12288.0 372.4 0 0.000 0 0.000 0.000
3072.0 3072.0 0.0 0.0 24576.0 491.5 122880.0 0.0 12288.0 372.4 0 0.000 0 0.000 0.000
3072.0 3072.0 0.0 0.0 24576.0 491.5 122880.0 0.0 12288.0 372.4 0 0.000 0 0.000 0.000
3072.0 3072.0 0.0 3072.0 24576.0 492.6 122880.0 21190.4 12288.0 373.3 1 0.022 0 0.000 0.022
3072.0 3072.0 0.0 3072.0 24576.0 492.6 122880.0 21190.4 12288.0 373.3 1 0.022 0 0.000 0.022
3072.0 3072.0 0.0 3072.0 24576.0 492.6 122880.0 21190.4 12288.0 373.3 1 0.022 0 0.000 0.022
3072.0 3072.0 0.0 3072.0 24576.0 492.6 122880.0 21190.4 12288.0 373.3 1 0.022 0 0.000 0.022

这个触发了Minor GC后为什么不是把所有的对象都弄到旧生代里,而是有些还在Suvirvor里呢?



------解决方案--------------------
没弄明白
------解决方案--------------------
-Xmx150M为150M 新生代有120M 老年代30M
for(int i=0;i<23285; i++)
{
objects.add(new DataObject(1));
}
每次创建1k共计也就23M左右,不会触发GC
------解决方案--------------------
Minor GC并不会马上把还有引用的对象放到老年代,而是对对象进行标记,如果超过了一定的标记数则会放入Suvirvor中,然后再放入老年带中,Suvirvor只是一个中间暂放区域,其实主要还是要取决于GC种类,上面所说的基于对象标记垃圾回收机制:)
------解决方案--------------------
年轻代还做了划分,包含S0,S1,Minor GC时,把对象先移到S0(也可能是S1),再移到S1(或S0),S1、S0都是相对而言,并没有真正规定那个是S0、S1,同一时间,S0、S1只能有一个往老年代转移对象。忘得差不多了,LZ先看看JVM内存模型,再看看各个分区的功能,有助于理解的。