《深入java虚拟机》读书笔记之垃圾收集器与内存分配策略 (7)

Minor GC:当Eden区可分配的内存不足以创建对象时就会触发一次Minor GC,Minor GC发生在新生代,由于新生代中大多数对象都是使用过后就不需要所以Minor GC的触发非常频繁。在Minor GC中存活下来的对象会被移到Survivor中,如果Survivor内存不够就直接移动到老年代。

full GC:当准备要触发一次young GC时,如果发现统计数据说之前young GC的平均晋升大小比目前old gen剩余的空间大,则不会触发young GC而是转为触发full GC(因为HotSpot VM的GC里,除了CMS的concurrent collection之外,其它能收集old gen的GC都会同时收集整个GC堆,包括young gen,所以不需要事先触发一次单独的young GC)。或者,如果有perm gen的话,要在perm gen分配空间但已经没有足够空间时,也要触发一次full GC;或者System.gc()、heap dump带GC,默认也是触发full GC。本内容来源于R大回答。

对象分配

在大多数情况下,对象的内存分配都优先在Eden中进行分配,当Eden区可分配的内存不足以创建对象时就会触发一次Minor GC。将Eden区和其中一块Survivor区内尚存活的对象放入另一块Survivor区域。如Minor
GC时survivor空间不够,对象提前进入老年代,老年代空间不够时就进行Full GC。大对象直接进入老年代,避免在Eden区和Survivor区之间产生大量的内存复制,虚拟机提供了一个-XX:PretureSizeThreshold参数,令大于这个值得对象直接进入老年代,但是该参数支队Serial和ParNew收集器有效。 此
外大对象容易导致还有不少空闲内存就提前触发GC以获取足够的连续空间。

这里大对象主要是指那种需要大量连续内存的java对象,比如大数组或者特别长的字符串等。

对象晋级

年龄阈值:虚拟机为每个对象定义了一个对象年龄(Age)计数器, 经第一次Minor GC后
仍然存活,被移动到Survivor空间中, 并将年龄设为1。以后对象在Survivor区中每熬
过一次Minor GC年龄就+1。 当增加到一定程度(默认
15),将会晋升到老年代(晋级的年龄可以通过-XX:MaxTenuringThreshold进行设置)。

提前晋升: 动态年龄判定,如果在Survivor空间中相同年龄所有对象大小的总和大
于Survivor空间的一半, 年龄大于或等于该年龄的对象就可以直接进入老年代,而无
须等到晋升年龄。

空间分配担保

在前面说垃圾收集算法时关于复制对象有说过可能会存在存活下来的对象无法被survivor容纳,这时就需要老年代容纳无法被survivor容纳的对象。而如果老年代也没有足够的空间来存放这些对象的话就会触发一次Full GC。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygpfp.html