垃圾回收 (計算機科學)





垃圾回收英语:Garbage Collection,縮寫為GC),在計算機科學中是一種自動的記憶體管理機制。當一個電腦上的動態記憶體不再需要時,就應該予以釋放,以讓出記憶體,這種記憶體資源管理,稱為垃圾回收。垃圾回收器可以讓程式員減輕許多負擔,也減少程式員犯錯的機會。垃圾回收最早起源于LISP语言。[1][2]目前許多語言如Smalltalk、Java、C#和D语言都支援垃圾回收器。




目录






  • 1 特徵


  • 2 分类


    • 2.1 收集器实现


    • 2.2 回收算法




  • 3 實作


  • 4 参见


  • 5 参考文献





特徵


垃圾回收器有兩個基本的原理:



  1. 考慮某個物件在未来的程式執行中,將不會被存取。

  2. 向這些物件要求歸回記憶體。



分类



收集器实现


  • 引用计数收集器

最早期的垃圾回收实现方法,通过对数据存储的物理空间附加多一个计数器空间,当有其他数据与其相关时则加一,反之相关解除时减一,定期检查各储存对象的计数器,为零的话则认为已经被抛弃而将其所占物理空间回收。是最简单的实现,但存在无法回收循环引用的存储对象的缺陷。

  • 跟踪收集器

近现代的垃圾回收实现方法,通过定期对若干根储存对象开始遍历,对整个程序所拥有的储存空间查找与之相关的存储对象和没相关的存储对象进行标记,然后将没相关的存储对象所占物理空间回收。


回收算法


基于其标记和回收行为,又分为若干细致方法。


  • 标记-清除

先暂停整个程序的全部运行线程,让回收线程以单线程进行扫描标记,并进行直接清除回收,然后回收完成后,恢复运行线程。這樣会导致大量零碎的空闲空间碎片,和使大容量对象不容易获得连续的内存空间,而造成空间浪费。

  • 标记-压缩

和“标记-清除”相似,不同的是,回收期间同时会将保留的存储对象搬运汇集到连续的内存空间。从而整合空闲空间。

  • 复制

需要程序将所拥有的内存空间分成两个部分。程序运行所需的存储对象先存储在其中一个分区(定义为“分区0”)。同样暂停整个程序的全部运行线程后,进行标记后,回收期间将将保留的存储对象搬运汇集到另一个分区(定义为“分区1”),完成回收,程序在本次回收后将接下来产生的存储对象会存储到“分区1”。在下一次回收时,两个分区的角色对调。

  • 增量回收器

需要程序将所拥有的内存空间分成若干分区。程序运行所需的存储对象会分布在这些分区中,每次只对其中一个分区进行回收操作,从而避免程序全部运行线程暂停来进行回收,允许部分线程在不影响回收行为而保持运行,并且降低回收时间,增加程序响应速度。

  • 分代


由于“复制”算法对于存活时间长,大容量的储存对象需要耗费更多的移动时间,和存在储存对象的存活时间的差异。需要程序将所拥有的内存空间分成若干分区,并标记为年轻代空间和年老代空间。程序运行所需的存储对象会先存放在年轻代分区,年轻代分区会较为频密进行较为激进垃圾回收行为,每次回收完成幸存的存储对象内的寿命计数器加一。当年轻代分区存储对象的寿命计数器达到一定阈值或存储对象的占用空间超过一定阈值时,则被移动到年老代空间,年老代空间会较少运行垃圾回收行为。一般情况下,还有永久代的空间,用于涉及程序整个运行生命周期的对象存储,例如运行代码、数据常量等,该空间通常不进行垃圾回收的操作。

通过分代,存活在局限域,小容量,寿命短的存储对象会被快速回收;存活在全局域,大容量,寿命长的存储对象就较少被回收行为处理干扰。



實作


GC的來源可能是由程式語言本身內建(如Java、C#)或是經由外面的函式庫所提供,而非建制於語言內部,例如貝姆垃圾收集器就是一種可支援C/C++語言的自動記憶體管理工具。


現今的GC(如Java和.NET)使用分代收集(generation collection),依照物件存活時間的長短使用不同的垃圾收集演算法,以達到最好的收集效能。


以Java為例,整個Java堆可以切割成為三個部分:



  1. Young:

    1. Eden:存放新生物件。

    2. Survivor:存放經過垃圾回收沒有被清除的物件。

    3. semi-Spaces:和Survivor做Copying collection。



  2. Tenured:物件多次回收沒有被清除,則移到該區塊。

  3. Perm:存放載入的類別還有方法物件。


Java不同的世代使用不同的GC演算法。



  1. Minor collection:

    YOUNG世代使用將Eden還有Survivor內的資料利用semi-space做複製收集(Copying collection),

    並將原本Survivor內經過多次垃圾收集仍然存活的物件移動到Tenured。



  2. Major collection則會進行Minor collection,Tenured世代則進行標記壓縮收集。



参见


  • 内存管理


参考文献





  1. ^ Recursive functions of symbolic expressions and their computation by machine, Part I. Portal.acm.org. [29 March 2009]. 


  2. ^ Recursive functions of symbolic expressions and their computation by machine, Part I. [29 May 2009]. (原始内容存档于2013-10-04). 





Template:约翰·麦卡锡





Popular posts from this blog

Lambaréné

Chris Pine

Kashihara Line