JVM的垃圾回收策略有很多种,标记清除回收器,压缩回收器,分代回收器。
比较常见的是sun公司实现的jvm的分代回收器。
堆内存被分位三代:年轻代(young generation),终生代(Tenured generation)[老说法年老代(old generation)],永生代(perm generation)
其中年轻代又分位eden区和两个survivor区(from survivior和to survivior)
永生代比较稳当,主要存放的类的加载信息
内存申请的过程
1 在eden区申请内存,如果容量够责,继续工作;
2 如果eden区内存余量不够,调用minor gc(另一说法young gc),把eden区的内存回收掉,如果还是不够,则把这些还有引用的堆对象,转移到from suvivor区
3 suvivor区是eden区和old区的中间区域,当old区有空间时,会把suvivor区的对象转移到old区中,如果old区也满了,则suvivor区和old区存放对象。
4 当再次往eden区申请空间时,old区,suvivor区都是满的时,调用full gc
5 当full gc后,eden区仍然无法申请到空间时,则报out of memory
其中young gc很快,full gc会很耗时,在执行gc的过程中,jvm上的程序是不工作的,所以应该,减少full gc的次数。
jvm参数的设置,也是通过设置一些比例参数,减少full gc的次数。
对象衰老的过程(生命周期):
GC类型 | 触发条件 | 触发时发生了什么 | 查看方式 | |
YGC | eden空间不足 | 清空Eden+from survivor中所有no ref的对象占用的内存 重新调整Eden 和from的大小(parallel GC会触发此项) | jstat –gcutil gc log | |
FGC | old空间不足 | 清空heap中no ref的对象 permgen中已经被卸载的classloader中加载的class信息 |