垃圾回收器如何工作

来源:互联网 发布:搜狗输入法云计算进程 编辑:程序博客网 时间:2024/06/05 11:47

垃圾回收器如何工作
转自:http://blog.csdn.net/lc18n/article/details/52264051

垃圾回收器对于提高对象的创建速度具有明显的效果。

java从堆分配空间的速度可以和其他语言从堆栈中分配空间的速度相媲美。
比如:C++中堆的内存分配类似于一个院子中给每个对象分配一块底盘。而java中堆的内存分配更像是一个传送带,每分配一个新对象,它就向前移动一格。这相当于无脑分配,故而速度非常快。之所以可以这样实现,得益于垃圾回收器的存在。通过垃圾回收器对对象重新排列,实现了一种高速的、有无限空间可供分配的堆模型。

垃圾回收技术历史发展回顾:
最早:
引用计数法,每当一个引用连接到一个对象时,该对象的引用计数加1,当取消连接时,计数减1。这种情况下垃圾回收器遍历全部对象,计数为0的,视作垃圾,全部回收。
弊端:循环引用,A,B,两个对象都是不需要的,但是A,B之间互相引用,导致A,B计数都不为零,则垃圾回收器无法回收。

发展:
只保留“活”的对象。因为任何“活”的对象,一定能最终追溯到其存活在堆栈或静态存储区之中的引用。所以,从堆栈和静态存储区向外遍历所有的引用,得到的对象都是“活”的,其他的部分就视作垃圾。

java虚拟机采用的是一种自适应的垃圾回收技术。
自适应:也就是说有两种模式自动切换。
一种是“停止-复制”模式;另一种是“标记-清扫”模式。两种模式都必须在程序暂停的情况下才能进行。

后期又提出了“分代”(分块计数(generation count,故称为代数))技术进行了优化。

停止-复制:
将所有“活”的对象从当前堆复制到另一个堆,没有被复制的都是垃圾。
这种情况下,当对象复制到新堆时是紧凑排列的。

标记-清扫:
每当找到一个“活”的对象时,给它一个标记,当全部对象标记完成后,开始清理没有被标记的对象。
这种模式下,不会发生任何复制动作,只是释放垃圾空间,所以会导致堆空间不连续。
这种模式适用于程序进入稳定状态后,只会产生少量垃圾甚至没有垃圾的情况下。

分代:
java虚拟机中,内存分配以“块”为单位。如果对象较大,会为其分配单独的“块”。每个“块”都有相应的“代数”来记录它是否还存活。每被引用一次,代数加一。垃圾回收器在回收时,会直接向废弃的“块”里拷贝对象。
这种情况下,较大的对象可以不用每次都复制,从而提高了效率。

原创粉丝点击