1. 程式人生 > 遊戲 >《幽靈線:東京》新預告片公開 展示主要劇情人物

《幽靈線:東京》新預告片公開 展示主要劇情人物

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),沿著有向邊遍歷整個圖,不可達的物件就是要清理的物件。這個根物件就是全域性物件,呼叫棧,暫存器。