本頁使用了標題或全文手工轉換

垃圾回收 (電腦科學)

維基百科,自由的百科全書
跳至導覽 跳至搜尋

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

特徵[編輯]

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

  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世代則進行標記壓縮收集。

參見[編輯]

參考文獻[編輯]

Template:約翰·麥卡錫