一、对象优先在Eden分配
1、 设置虚拟机常规参数
2、代码展示:
问题:Minor GC 与Full GC有什么不一样么?
解答:
新生代GC(Minor GC),指发生在新生代的垃圾收集动作,因为java对象大多数都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。
老年代(Major GC、Full GC):指发生在老年代的GC,出现Major GC,经常会伴随至少一次的Minor GC(并不是绝对的)。 Major GC的速度一般会比Minor GC慢10倍以上。
3、结果分析:
GC日志中停顿类型基本分为两种:
1:full gc(说明是发生了Stop-the-World.。 比如:调用了system.gc())
2:gc
defNew :表示GC发生的区域,这里显示的区域名与使用的GC收集器是密切相关的。
6980k=》451k(9216K):含义是GC前该内存区域已使用容量=》GC后该内存区域已使用容量(该内存区域总容量)。
方括号之外的,6980k=》6595k(19456)k,含义是GC前Java堆已使用容量=》GC后Java堆已使用容量(java堆总量)
0.014999 secs:表示该内存区域GC所占用的时间。
内存分析:在alloction4分配内存时,Eden代中,已经有了6M的对象,已经不足以放下4M的alloction4,因此发生Minor GC
。GC期间,虚拟机发现已有的3个2M的对象全部无法放入Survivor中(只有1M),所以之后通过分配担保机制提前转移到老年代中
有的收集器会给出更具体的时间数据。
user:代表用户态消耗的CPU时间
sys:内核态消耗的CPU时间
real:操作从开始到结束所经过的墙钟时间。
CPU时间和墙钟时间的区别:
墙钟时间包括各种非运算的等待耗时,例如等待磁盘I/O,等待线程阻塞。而CPU时间不包括这些耗时,但当系统有多CPU或者多核时,多线程操作会叠加这些CPU时间,所以读者看到user或sys时间超过real时间是完全正常的。
二、大对象直接进入老年代
所谓大对象是指:需要大量连续内存空间的java对象。 经常出现大对象容易导致内存还有不少空间时,就提前触发垃圾收集以获取足够的连续空间。
1、 设置虚拟机常规参数
2、代码展示:
3、结果分析:
我们能够看到,4MB的对象,直接进入到了老年代中。
三、长期存活的对象将进入老年代
问题:如何判定一个在新生代分配内存的对象,什么时候能够进入老年代?
解答:虚拟机给每个对象定义了一个对象年龄(Age)。如果对象在新生代出生,且经历过一次Minor GC后仍然存活,并且能够被survivor所容纳的话,将被移动到survivor中,并且将他的age设为1。对象在survivor中,每“熬过”一次minor GC,年龄+1,当它的年龄增加到一定程度(默认15岁),就会被晋升到老年代中。
年龄阀值设置:-XX:MaxTenuringThreshold
1、设置虚拟机参数 和 代码展示
2、第一次: -XX:MaxTenuringThreshold=1 运行结果:
3、第二次: -XX:MaxTenuringThreshold=15 运行结果:
未完待续........