迴圈引用和解決方案
阿新 • • 發佈:2019-01-04
如何處理迴圈引用問題?
什麼是迴圈引用?
顧名思義,兩個物件之間形成環路。對於C++中兩個物件來講,使用智慧指標解決不了這個問題。因為其引用計數不為0。
迴圈引用解決辦法
迴圈引用涉及的問題是垃圾回收(Garbage Collection,GC)。垃圾就是不再被引用的物件。討論基本的垃圾回收演算法。
(1)引用計數演算法
原理:唯一一種不用根集概念的GC演算法。為每個物件加一個計數器,記錄所有指向該物件的引用數量。根據計數值判斷該物件的狀態。
優點:實現簡單,在原生不支援GC的語言中容易實現出來。即時回收,物件不再被引用時立即釋放。
缺點:不能解決迴圈引用問題 。再者,當多個執行緒同時對引用計數進行增減時,引用計數的值可能會產生不一致的問題,必須使用併發控制機制解決這一問題,也是一個不小的開銷。
(2)Mark & Sweep演算法
原理:動態申請記憶體時先按需分配,當記憶體不足時則從暫存器、程式棧上的引用(程式設計師寫的)出發,遍歷上述的有向可達圖,對不能到達的物件進行標記。然後再次遍歷,釋放未標記的物件。
缺點:在分配大量物件時,且物件大都需要回收時效率偏低。因為要遍歷2次。
(3)節點複製演算法
原理:從根節點開始遍歷,被引用的物件會被複制到一個新的區域,剩下的即為垃圾。釋放記憶體時,直接把原來的儲存區釋放。
優缺點:當需要回收的物件越多時,開銷很小。當大部分物件不再需要回收時,開銷反而很小。
這三種是基本演算法。可以在此基礎上改進融合。
C語言本身沒有提供GC機制。而C++ 0x則提供了基於引用計數演算法的智慧指標進行記憶體管理。也有一些不作為C++標準的垃圾回收庫,如著名的Boehm庫。藉助其他的演算法也可以實現C/C++的GC機制,如前面所說的標記清除演算法。