java的垃圾回收绝大多数发生在堆上。
堆可分为新生代和老年代。新生代又分为三个区:伊甸区,幸存0区和幸存1区,即
(Eden,Survivor0和Survivor1)。
GC算法
1.标记清除算法
标记清楚算法会为每个对象设置一个标记位,其分为两个阶段。第一个阶段会检查对象是否死亡,并更新标记。第二个阶段会清除死亡的对象。
缺点:清除过后会产生碎片,并且扫描两次,浪费时间。
2.标记压缩算法
这个算法是标记清除算法的改进版。其分为三个阶段。第一个阶段检查对象是否死亡,并对其进行标记。第二个阶段会清楚死亡的对象。第三个阶段会对存活的对象进行整理,减少碎片。
优点:不会产生碎片。
缺点:浪费时间
3.复制算法
当系统创建一个对象的时候,会将其放到新生区的伊甸区。伊甸区满了之后,会出发Minor GC,此时会将伊甸区的对象移动到其中一个存活区,也可成为from区,此时另一个存活区的对象也会移动到to区。此时伊甸区和另一个存货区(to区)都为空。系统继续在伊甸区创造对象。当伊甸区再次满的时候,系统会再次出发Minor GC,会将伊甸区和from区还存活的对象移动到to区。此时原来的from区为空,成为to区。原来的to区有了对象,成为from区。to区永远为空。
若新生区的对象存活一定时间后,会将其移动到老年代。若老年代满了,会触发Full GC。当存活对象数量较少时,此算法效率较高。
优点:没有内存碎片。
缺点:浪费空间,to区永远为空。