Java中的垃圾回收

来源:互联网 发布:康复站立架淘宝 编辑:程序博客网 时间:2024/06/11 07:34

http://www.52z.com/info/html/28735.html


Java中的垃圾回收

出处:本站整理 作者:佚名 日期:2010-01-11 评论(0)条

先说明一下,垃圾回收机制需要付出的代价是运行时开销。在C++中,在堆栈中创建对象,可以通过编程被清理,所以说,在堆栈上创建对象是最有效的为对象分配和释放储存处空间的途径。在堆上创建对象代价要高昂得多!垃圾回收器有一个特殊的问题:你从来都不确切知道它将于何时启动并持续多久!除非直接用System.gc()调用(建议不要这样用),这意味着一个Java程序的执行速度会有前后不一致的情况出现。因此,实时系统不适合用Java进行开发。



1、“引用计数”是一种简单但是速度很慢的垃圾回收技术。

每个对象有一个引用计数器,当有引用连接至对象时,引用计数加1。当引用离开作用域或被置为null时,计数器减1。当需要回收时,垃圾回收器(GC)会在含有全部对象的列表上遍历,当发现某个对象的引用计数为0,就释放其占用的空间。缺陷:如果对象之间出现循环引用(即对象内部存在引用指向另一个对象,而另一个对象又存在引用指向自己),就会出现无法回收的情况。因此,该方法一般不会用于任何一种Java虚拟机的实现。

2、“停止-复制”(stop-and-copy)技术。

先暂停程序的运行,然后将所有存活对象从当前堆复制到另一个堆,没有被复制的全部都是垃圾,把对象从一个堆复制到另一个以后,所有指向它的引用都必须修正。缺陷:a、需要有两个堆,即需要多一倍的空间。b、当程序稳定执行时,可能只产生少量垃圾,此时将所有对象复制到另一个堆是一个浪费时间但是又没有效果的事情。

3、“标记-清扫”(mark-and-sweep)技术。

先暂停程序的运行,然后同“停止-复制”法一样,从堆栈和静态存储区出发,遍历所有引用,进而找出所有存活的对象,每当找到一个存活对象,就会给该对象设置一个标记,这个过程中不会回收任何对象。只有全部标记工作完成了以后,清理工作才会开始。没有被标记的对象将会被释放。缺陷:剩下的堆空间是不连续的,GC如果希望得到连续空间的话,就得重新整理剩下的对象。

4、一般地,Java虚拟机会先执行“停止-复制”,同时进行监视,如果所有对象都很稳定,GC效率降低的话,就切换到“标记-清扫”方式;同样,Java虚拟机会跟踪“标记-清扫”的效果,要是堆空间出现很多碎片,就会切换回“停止-复制”方式。即“自适应”技术。