一、垃圾回收机制的意义
java中一个显著的特点就是引入了垃圾回收机制,有效的解决了C语言中的内存管理问题。由于有垃圾回收机制,java中不需要再考虑内存管理问题,java中对象不再有作用域的概念,只有在引用对象的时候才有作用域的概念,垃圾回收可以有效的防止内存泄露,有效的使用内存空间。
内存泄露:就是指该内存空间使用完毕后未进行回收,在不涉及复杂算法的前提下,java中的内存泄露表现为内存对象的生命周期超出了程序需要它的时间长度,也可将其称为“对象游离”。
二:垃圾回收机制中的算法
任何垃圾回收机制算法中都有基础的两点:(1)、发现无用对象。(2)回收被无用对象占用的内存空间,使该空间可以再次被程序使用。
1、引用计数法(Reference counting collector)
算法分析:
引用计数是垃圾收集器中的早期策略,在这种方法中,堆中每个对象实例都有一个引用计数,当一个对象被创建时,且将该对象分配给一个变量,则该变量计数设置为1。当任何其他变量赋值为这个对象的引用时,计数加1(a = b 则b引用的对象实例计数加1),但当一个对象的某个引用实例超过了生命周期或者被设置为一个新值的时候,对象实例的引用计数器减一。任何引用计数器为0的对象实例可以被当做垃圾收集,当一个对象实例的被回收时,它引用的任何对象实例的引用计数器减一。
对象生命周期:
对象整个生命周期大致可分为七个阶段:创建阶段、应用阶段、不可视阶段,不可到达阶段、可收集阶段、终结阶段、释放阶段。
优点:
引用计数器可以很快的执行,交织在程序运行中,对于程序需要不被长时间打断的实时环境很有利。
缺点:
无法检测循环引用,如父对象对子对象有一个引用,子对象反过来引用父对象,那么他们的引用计数永远不可能为0。
引用计数无法解决循环引用问题。
2、tracing算法(tracing collector),或标记-清除算法(mark and sweep)
跟搜索算法:
跟搜索算法是从离散数学中的图论引入的,程序把所有的引用关系看成一张图,从一个节点GC ROOT开始,寻找对应的引用节点,找到节点后,继续寻找该节点的引用节点,当所有引用节点寻找完毕后,剩余的节点则被认为是没有被引用到的节点,即无用的节点。
java中可作为GC ROOT的对象有
(1)、虚拟机栈中引用的对象(本地变量表);
(2)、方法中静态属性引用的对象;
(3)、方法中常量引用的对象;
(4)、本地方法栈中引用的对象(Native)
标记清除算法分析:
该算法采用从根集合扫描。对存活的对象进行标记,标记完毕后再扫描整个空间中未被标记的对象,进行回收。标记算法不需要对对象进行移动,并且仅对不存活的对象进行处理,在存活对象比较多的情况下比较高效,但由于直接回收不存活对象,因此会产生内存碎片。