VueRouter配置-2-index.js檔案
阿新 • • 發佈:2022-02-27
Python垃圾回收機制,以引用計數為主標記清除和分代回收為輔。
一、引用計數器
cPython中會對建立的物件進行計數(ob_refcnt)。每當被引用一次就+1,取消引用就-1。當ob_refcnt=0時就表示沒有被引用了,這時垃圾回收機制就會啟動將這個物件回收。
class Obj_gc_A(): def __del__(self): # 物件被回收後,會執行__del__函式 print("Obj_gc_A進行了垃圾回收") class Obj_gc_B(): def __del__(self): print("Obj_gc_B進行了垃圾回收") a = Obj_gc_A() b = Obj_gc_B() print("垃圾回收__前") a = 1 b = 2 print("垃圾回收__後") 垃圾回收__前 Obj_gc_A進行了垃圾回收 Obj_gc_B進行了垃圾回收 垃圾回收__後
引用計數的優點
- 簡單
- 實時性高,只要引用計數為0,物件就會被銷燬,記憶體被釋放,回收記憶體的時間平攤到了每個時間點。
引用計數的缺點
- 為了維護引用計數消耗了很多資源。
- 迴圈引用導致記憶體洩露。
# 迴圈引用例子
l1 = [] l2 = [] l1.append(l2) l2.append(l1)
二、標記清除
引用計數並不能解決所有的問題,一旦出現了迴圈的引用,那麼這些物件的引用次數永遠都是大於0的,但是這些物件都是不會用的垃圾資料。
class Obj_gc_A(dict): def __del__(self): print("Obj_gc_A進行了垃圾回收") class Obj_gc_B(dict): def __del__(self): print("Obj_gc_B進行了垃圾回收") a = Obj_gc_A() b = Obj_gc_B() a["xx"] = b b["yy"] = a print("垃圾回收") 輸出 垃圾回收 Obj_gc_A進行了垃圾回收 Obj_gc_B進行了垃圾回收
標記清楚可以處理這種迴圈引用的情況,它分為兩個階段。
第1階段,標記階段
GC會把所有的活動物件打上標記,這些活動的物件就如同一個點,他們之間的關係構成為邊。最終點和邊構成一個象圖。
第2階段,搜尋清除階段
從根物件出發(root),沿著有向邊遍歷整個圖,不可達的物件就是要清理的物件。這個根物件就是全域性物件,呼叫棧,暫存器。