垃圾回收
什么是垃圾
jvm中new出来的对象,没有任何引用指向它的时候,它就是垃圾。
垃圾的定位
引用计数
当引用计数变为0的时候就成为垃圾了。
但是,引用计数会没有办法定位循环引用的垃圾对象,
例如,有三个对象互相引用,
但是没有其它外部引用指向它们,它们其实都是垃圾。
垃圾抱起团来也是一堆垃圾(笑cry)。
可达分析
Java采用的是这种方法
将"GC Roots"作为起点,从这些节点开始向下搜索引用的对象,
整条引用链上的对象都被标记为非垃圾,其余未被标记的对象都是垃圾。
GC Roots:线程栈的本地变量、静态变量、本地方法栈的变量等。
垃圾的回收
三种方法
标记清除
标记→然后清除
优点:方法简单,存活对象较多的情况下效率较高,
缺点:两边扫描,效率偏低,也容易产生碎片。
因为回收的这些空间会产生不连续的内存。
拷贝
将空间一分为二,其中一半不用,
回收时将存活的对象整齐拷贝到另一半空间。
优点:没有碎片,
缺点:浪费空间,永远都有一半空间是空闲着的。
标记压缩
标记→然后清除的时候顺带整理好空间
它是消耗时间较长,效率最低的一种,因为边清除边整理。
这三种方法各有特点,实际运用中一般是结合使用。
堆内存分区
年轻代大量死去,少量存活,采用拷贝方法回收,
老年代存活率高,回收较少,采用MS或MC,即标记清除和标记压缩。
伊甸园区的回收会有一个特点,就是经过一次回收后会有大量对象被清除,
回收范围包括伊甸园区和当前的幸存者区,经历过minor GC存活下来的对象,分代年龄会+1,
分代年龄未达到一定值,例如15,会被被拷贝到另外一个幸存者区,否则移动到老年代。
这些情况对象会被放到老年代(对象的分配)