think in Java 第五章之垃圾回收类型

1.引用计数:

  每个对象都含有一个引用计数器,当有引用连接至对象时,引用计数加1,当引用离开作用域或被置为null时,引用计数减1.

  缺陷:在对象循环引用时,存在“对象应该被回收,引用计数却不为0”的情况。

  常用来说明垃圾收集的工作方式,当没有被任何Java虚拟机应用。

2.基于:对任何“活”的对象,一定能最终追溯到其存活在堆栈或静态存储区域中的引用的思想。从堆栈或静态区域开始,遍历所有的引用,就能找到所有活着的对象。

  在这种方式下,Java虚拟机采用一种自适应的垃圾回收技术。至于如何处理找到的存活对象,取决于不同Java虚拟机的实现。

  (1)停止-复制(stop-and-copy):先暂停程序运行(所以不属于后台回收模式),然后将所有的存活对象从当前堆复制到另一个堆,没有被复制的全部都是垃圾。当对象被复制到新堆时,它们是一个挨着一个的,所以新堆保持紧凑。

  当一个对象从一处被搬到另一处,所有指向它的引用都得修改,位于堆或静态存储区域的引用可以直接被修正,但可能还有其他指向这些对象的引用,它们在遍历的过程中才能被找到。

  缺陷:效率低。a.两个堆来回倒腾,需要维护比实际多一倍的空间。某些虚拟机对此处理的方式是,按需从对中分配几块较大的内存,复制动作发生在这些较大块的内存之间。b.复制,程序稳定后,可能只有少量或者没有垃圾,复制式回收器仍然会复制,这相当浪费。为避免这种情形,一些虚拟机会进行检查:没有新垃圾产生时,转到另一种工作模式(即自适应)。

  (2)标记-清除(mark-and-sweep),当找到活的对象时,给存活对象设一个标记,这个过程中不会回收任何对象。当全部标记工作完成时,清理动作才会开始。清理过程中,没有被标记的对象将被释放,标记对象不会复制。(速度慢,但只有少量垃圾甚至没有垃圾时,速度很快)

  以上两种方式都必须在程序暂停的情况下才能进行。

3.自适应技术:

  Java虚拟机中,内存分配以较大的块为单位,如果对象较大,它会占单独的块,“停止-复制”有了块以后,垃圾回收器在回收的时候就可以往废弃的块里拷贝对象。每个块都有相应的代数(generation count)来记录是否存活。通常块在某处被引用代数就会增加,回收器对上次回收动作之后新分配的块进行整理。这对处理大量的短命 的临时对象很有帮助。垃圾回收器会定期进行完整的清理工作-大型对象不会被复制(只是其代数会增加),内含小型对象的那些块则被复制并整理。Java虚拟机会进行监视,如果所有对象都很稳定,垃圾回收器的效率降低,就切换到“标记-清除”方式;同样,Java虚拟机会跟踪“标记-清除”的效果,要是对空间出现很多碎片,就会切换回“停止-复制”方式。

posted @ 2016-05-16 15:09  luffly  阅读(172)  评论(0编辑  收藏  举报