关于java GC回收的一点心得

来源:互联网 发布:倍增时代软件好用吗 编辑:程序博客网 时间:2024/05/22 03:39

最近在复习java GC方面的知识,本博客作为复习心得的记录与回顾。

学过c++的都知道,创建一个类,要用到构造函数,而当一个类对象使用完毕后,就需要程序员显示的调用析构函数进行回收处理。这种把回收权利交给程序员的做法,有利有弊,对于技术大牛来说,可以更好的对程序进行调优处理,而对于一般的程序员来说,可能只是增加了程序编写的复杂度。而Java,有自己的一套回收机制, 并且控制权在jvm手中,这样能更好的减轻程序员的负担,但是也会增加系统开销,利弊与否,见仁见智。

下面来说一下GC回收中的算法与算法的演进迭代。

GC回收算法离不开两种,跟踪回收和引用计数。美国IBM的沃森研究中心David F.Bacon等人发布的【垃圾回收统一理论】一文中阐述了一个理论:GC垃圾回收的思路,无非是上面两种的组合,其中一种的改善和进步,必然伴随着另一种的改善和进步。

在说第一种标记回收算法前,先说一下引用计数算法,引用计数的算法就是对对象添加一个引用计数器,当该对象被引用时,计数器加一,当引用失效时,计数器减一,如果计数器一直为0,则表示对象不被引用。然后在垃圾回收时,该对象就会被回收。但是,在实际应用时,会出现这样一个问题,如果两个或多个对象被互相引用,这些对象的计数器永远不会为0,这样就无法回收了。于是,经过技术和算法的演进,有了第一种被广泛应用的算法,标记法。

标记法:它是第一个可以回收被循环引用的数据结构的垃圾回收算法,现在仍旧有许多常用的垃圾回收技术使用各种各样的标记清除算法的变体。标记清除对象需要对程序的对象进行两次扫描。第一次扫描是从root根目录进行,被根引用的对象被标记为不是垃圾,当然包括被根引用的对象的对象也不是垃圾,依次递归,直到遍历所有节点。第一次扫描完,进行第二次扫描,然后将所有被标记为垃圾的对象进行清除。

复制收集:复制收集的方式只需要对对象进行一次扫描。将所有不是垃圾的对象及其引用复制到新空间,然后直接删除旧空间的所有数据,以此来达到垃圾回收的目的。但是,对于失去引用对象数量不多的情况,效率低下。而对于垃圾对象比例大大超过不需要回收对象的比例时,效率极高。

这两种回收算法方式各有千秋,对于标记法,回收时所占用的空间比较小,但是耗时比较长。而对于复制收集的回收方式,耗时短,但需要额外更多的空间,但是复制回收有一个【局部性】的特点。意思是,当对象及其对象的引用被复制出来时,会更加集中在相邻的物理地址中,在以后调用时,速度会很快。

以上是两种最基本的垃圾回收算法,垃圾算法发展至今,已经从中衍生出了分代回收,并行回收,增量回收。

原创粉丝点击