JAVA垃圾回收器

来源:互联网 发布:县令县丞县尉知具 编辑:程序博客网 时间:2024/05/17 02:14

       跟C++通过编程注销对象的方式不同,JAVA通过垃圾回收器完成内存的释放问题。

       当内存数量较低的时候,垃圾回收器就开始发挥作用了。跟很多人一样,我这种JAVA菜鸟对垃圾回收器的运行机制很感兴趣。垃圾回收器有两个功能,首先是释放没用的对象,再者是内存碎片的管理。垃圾回收器会自动完成无用对象的清除,问题就来了:垃圾回收器是如何判断一个对象是否应该被回收。在堆栈或者静态存储区中没有对象的引用的时候,垃圾回收器就认为这是无用的对象,需要清除。言外话,JAVA使用heap(堆)来存储对象,堆栈(Stack)存储对象的引用,两者都位于RAM区。有两种方法来知道一个对象是否被引用,第一种是遍历堆上的对象找引用,第二种是遍历堆栈或者静态存储区的引用找对象。对于前者,通过“引用计数法”实现,当有引用连接对象时,引用计数加1,当引用离开作用域,引用计数器减1,当计数器为0,对象就满足垃圾收集的条件。这种方式首先会加大程序运行开销,其次可能会出现对象应该被回收,但是引用计数器不为0的情况。

      JAVA采用的是第二种方法,JVM采用自适应的垃圾回收机制,如何处理存活对象,JAVA有两种方式:

      1.“stop-and-copy”:非后台回收模式,理论上要先暂停程序的运行。将存活的对象从当前堆复制到另一个堆,没有被复制的就是无用对象。

      2."make-and-sweep”:从堆栈和静态存储出发,遍历所有的引用,进而找出所有活的对象。对于找到的存活对象进行标记,全部标记完成后,没有标记的对象会被释放。

     当垃圾回收器第一次启动时,执行的是“stop-and-copy”,因为这个时候内存垃圾太多。当稳定后,就切换到“make-and-sweep”方式,根据堆空间的碎片情况,切换两种方式。

     大多数垃圾回收算法使用了根集(root set)这个概念;所谓根集就是正在执行的Java程序可以访问的引用变量的集合(包括局部变量、参数、类变量),程序可以使用引用变量访问对象的属性和调用对象的方法。垃圾回收首先需要确定从根开始哪些是可达的和哪些是不可达的,从根集可达的对象都是活动对象,它们不能作为垃圾被回收,这也包括从根集间接可达的对象。而根集通过任意路径不可达的对象符合垃圾收集的条件,应该被回收。

    具体的算法见:http://blog.csdn.net/zsuguangh/article/details/6429592


原创粉丝点击