1. 程式人生 > >迴圈引用和解決方案

迴圈引用和解決方案

如何處理迴圈引用問題?

什麼是迴圈引用?

顧名思義,兩個物件之間形成環路。對於C++中兩個物件來講,使用智慧指標解決不了這個問題。因為其引用計數不為0。

迴圈引用解決辦法

迴圈引用涉及的問題是垃圾回收(Garbage Collection,GC)。垃圾就是不再被引用的物件。討論基本的垃圾回收演算法。

(1)引用計數演算法

原理:唯一一種不用根集概念的GC演算法。為每個物件加一個計數器,記錄所有指向該物件的引用數量。根據計數值判斷該物件的狀態。

優點:實現簡單,在原生不支援GC的語言中容易實現出來。即時回收,物件不再被引用時立即釋放。

缺點:不能解決迴圈引用問題 。再者,當多個執行緒同時對引用計數進行增減時,引用計數的值可能會產生不一致的問題,必須使用併發控制機制解決這一問題,也是一個不小的開銷。

(2)Mark & Sweep演算法

原理:動態申請記憶體時先按需分配,當記憶體不足時則從暫存器、程式棧上的引用(程式設計師寫的)出發,遍歷上述的有向可達圖,對不能到達的物件進行標記。然後再次遍歷,釋放未標記的物件。

缺點:在分配大量物件時,且物件大都需要回收時效率偏低。因為要遍歷2次。

(3)節點複製演算法

原理:從根節點開始遍歷,被引用的物件會被複制到一個新的區域,剩下的即為垃圾。釋放記憶體時,直接把原來的儲存區釋放。

優缺點:當需要回收的物件越多時,開銷很小。當大部分物件不再需要回收時,開銷反而很小。

這三種是基本演算法。可以在此基礎上改進融合。

C語言本身沒有提供GC機制。而C++ 0x則提供了基於引用計數演算法的智慧指標進行記憶體管理。也有一些不作為C++標準的垃圾回收庫,如著名的Boehm庫。藉助其他的演算法也可以實現C/C++的GC機制,如前面所說的標記清除演算法。