垃圾回收 GC

垃圾回收(Garbage Collection,縮寫爲GC)

自動的存儲器管理機制。當某個程序佔用的一部分內存空間不再被這個程序訪問時,這個程序會藉助垃圾回收算法向操作系統歸還這部分內存空間。




收集器實現


引用計數收集器

爲佔用物理空間的對象 附加一個計數器,當有其他對象引用這個對象時計數器加一,反之引用解除時減一。
會定期檢查尚未被回收的對象的計數器,爲零的話則回收其所佔物理空間,因爲此時的對象已經無法訪問,但是這種方法無法回收循環引用的存儲對象。


跟蹤收集器。

會定期遍歷它管理的內存空間。從若干 “根” 存儲對象開始,查找與之相關的存儲對象,然後標記其餘的沒有關聯的存儲對象,最後回收這些沒有關聯的存儲對象佔用的內存空間。




回收算法

1:標記-清除

先暫停整個程序的全部運行線程,讓回收線程以單線程進行掃描標記,並進行直接清除回收,然後回收完成後,恢復運行線程。這樣會產生大量的空閒空間碎片,和使大容量對象不容易獲得連續的內存空間,而造成空間浪費。

2:標記-壓縮

和“標記-清除”相似,不同的是,回收期間同時會將保留的存儲對象搬運彙集到連續的內存空間,從而整合空閒空間,避免內存碎片化。

3:複製

需要程序將所擁有的內存空間分成兩個部分。程序運行所需的存儲對象先存儲在其中一個分區(定義爲“分區0”)。同樣暫停整個程序的全部運行線程,進行標記後,回收期間將保留的存儲對象搬運彙集到另一個分區(定義爲“分區1”),完成回收,程序在本次回收後將接下來產生的存儲對象會存儲到“分區1”。在下一次回收時,兩個分區的角色對調。

4:增量回收器

需要程序將所擁有的內存空間分成若干分區。程序運行所需的存儲對象會分佈在這些分區中,每次只對其中一個分區進行回收操作,從而避免暫停所有正在運行的線程來進行回收,允許部分線程在不影響回收行爲下保持運行,並且降低迴收時間,增加程序響應速度

5:分代

由於“複製”算法對於存活時間長,大容量的儲存對象需要耗費更多的移動時間,和存在儲存對象的存活時間的差異。需要程序將所擁有的內存空間分成若干分區,並標記爲年輕代空間和年老代空間。程序運行所需的存儲對象會先存放在年輕代分區,年輕代分區會較爲頻密進行較爲激進垃圾回收行爲,每次回收完成倖存的存儲對象內的壽命計數器加一。當年輕代分區存儲對象的壽命計數器達到一定閾值或存儲對象的佔用空間超過一定閾值時,則被移動到年老代空間,年老代空間會較少運行垃圾回收行爲。一般情況下,還有永久代的空間,用於涉及程序整個運行生命週期的對象存儲,例如運行代碼、數據常量等,該空間通常不進行垃圾回收的操作。 通過分代,存活在侷限域,小容量,壽命短的存儲對象會被快速回收;存活在全局域,大容量,壽命長的存儲對象就較少被回收行爲處理干擾。
現今的GC(如Java和.NET)使用分代收集(generation collection),依照對象存活時間的長短使用不同的垃圾收集算法,以達到最好的收集性能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章