JVM --- 垃圾回收
一、YGC和full GC的区别
-
YGC(minor GC):只针对新生代区域进行GC,发生得非常频繁,回收速度也很快;
-
Full GC(major GC):指发生在老年代的GC,出现了Full GC,经常会伴随至少一次以上的YGC,速度比YGC慢10倍以上,因为老年代和新生代空间分别是堆空间的2/3,1/3,老年代空间更大,当然回收更慢。
二、四大回收算法
垃圾回收有四大算法,这四种算法就是确定了这个对象是垃圾后,怎么进行回收。
-
引用计数法:对象被引用时加一,少一个引用时减一,当引用为零时,就是垃圾。这种方式的缺点就是每次对象赋值时都要维护引用计数器,这个计数器本身也有一定的内存消耗;第二个缺点就是较难处理循环引用。JVM一般不采用这种方式。
-
复制算法:新生代的YGC采用的就是这种算法。上一篇说了,伊甸园区进行YGC后存活的对象,就会使用复制算法复制到from区,from区和伊甸园区再次触发YGC后存活的对象,就会被复制到to区。该算法优点是,因为是全盘复制过去的,所以不会产生碎片,缺点是耗空间,from区有多大,to区也得有多大,这两个区大小是一比一;而且,假如某些极端的情况下,比如定义了很多静态的对象,伊甸园区对象进行YGC时,好多对象没被回收,那么要复制的对象就会很多。
-
标记清除:老年代采用的一般就是标记清除算法,或者是标记清除 + 标记整理混合实现。标记清除分为两步,先标记出要回收的对象,然后对这些被标记的对象统一回。优点是不会浪费额外的空间,缺点就是回收后的空间不是连续的,会产生内存碎片,且分两步进行,比较耗时。当JVM可使用内存快被耗尽时,GC线程就会暂停程序,随后标记要回收的对象,统一回收后,程序再恢复运行。
-
标记整理(标记压缩):上面说了标记清除算法不会浪费额外空间,但是会产生内存碎片。所以标记整理算法就是比标记清除又多了一步,整理那些不连续的空间(将存活的对象往一端滑动,后面的空间就是连续的了),这样就没有内存碎片了。缺点就是耗时。
那么哪种回收算法最好呢?没有最好,只有最合适。复制算法省时间,但是耗空间,标记整理算法不耗费额外的空间,但是费时间。新生区因为对象存活率底,所以适合用复制算法,而老年区适合用标记清除 + 标记整理。所以JVM垃圾回收算法又称为分代回收算法。