參照計數

參照計數(英語:reference countingRC)是電腦程式語言中的一種主記憶體管理技術,是指將資源(可以是對象主記憶體磁碟空間等等)的被參照次數儲存起來,當被參照次數變為零時就將其釋放的過程。使用參照計數技術可以實現自動資源管理的目的。同時參照計數還可以指使用參照計數技術回收未使用資源的垃圾回收演算法。

當建立一個對象的實例並在堆上申請主記憶體時,對象的參照計數就為1,在其他對象中需要持有這個對象時,就需要把該對象的參照計數加1,需要釋放一個對象時,就將該對象的參照計數減1,直至對象的參照計數為0,對象的主記憶體會被立刻釋放。

使用這種方式進行主記憶體管理的語言:Objective-CPythonVala等。

優勢與缺陷

跟蹤式垃圾回收相比,參照計數的主要優點是可以儘快地回收不再被使用的對象,同時在回收過程中不會導致長時間的停頓,還可以清晰地標明每一個對象的生存周期。

即時應用或主記憶體受限的系統中,即時回應能力是一項重要指標,而參照計數作為最容易實現的垃圾回收技術之一,很適合於這種情況。參照計數還可以用於管理其他非主記憶體資源,如作業系統對象(經常比主記憶體資源更稀缺)。跟蹤式垃圾回收技術用終端子處理此類目標,但延遲回收可能引發其他問題。加權參照計數是適用於分散式系統的衍生技術。

在可用主記憶體被活躍對象填滿的平台上,跟蹤式垃圾回收會被頻繁觸發,從而降低效能。而參照計數即便在主記憶體瀕臨耗盡的情況下效能依然有所保障。[1]參照計數還能為其他執行時最佳化技術提供參考資訊,例如對於許多使用不可變對象的系統來說(如函數式程式設計語言),大量複製對象導致的效能懲罰有時十分嚴重;在此類系統上一個典型的最佳化措施是:假如一個對象被建立以後僅使用了一次,且在其不再被參照的同時另一個類似的對象被建立出來(如Javascript中的字串拼接賦值操作),可以將刪除原對象新增對象的行為變為修改原對象,從而提高效率。參照計數可以為這類最佳化提供充分的參考資訊。

未經最佳化的參照計數相比跟蹤式垃圾回收有兩個主要缺點,都需要引入附加機制予以修復:

  • 頻繁更新參照計數會降低執行效率。
    • 對於Vala等在編譯時進行參照計數的語言一般較少存在這一問題[2]
  • 原始的參照計數無法解決迴圈參照問題。

另外,如果使用空閒列表分配主記憶體,那麼參照計數的空間局域性非常差。僅使用參照計數無法通過移動對象來提高CPU快取的效能,所以高效能的主記憶體分配器都會同時實現一個跟蹤式垃圾回收器以提高效能。許多參照計數實現(比如PHP和Objective-C)的效能不佳都是因為沒有實現主記憶體拷貝。[3]

Objective-C 範例

NSObject* obj = [[NSObject alloc] init];  //obj retain count is 1
obj = [obj1 retain];  //obj retain count is 2
[obj release];  //obj retain count is 1
[obj release];  //obj retain count is 0, obj was released

相關條目

參考資料

  1. ^ Wilson, Paul R. "Uniprocessor Garbage Collection Techniques". Proceedings of the International Workshop on Memory Management. London, UK: Springer-Verlag. pp. 1–42. ISBN 3-540-55940-X. Retrieved 5 December 2009. Section 2.1.
  2. ^ Projects/Vala/ReferenceHandling - GNOME Wiki!. wiki.gnome.org. [2022-10-07]. (原始內容存檔於2022-05-05). 
  3. ^ Rifat Shahriyar, Stephen M. Blackburn, Xi Yang and Kathryn S. McKinley (2013). "Taking Off the Gloves with Reference Counting Immix". 24th ACM SIGPLAN conference on Object Oriented Programming Systems, Languages and Applications. OOPSLA 2013. doi:10.1145/2509136.2509527.