Python類對象的生命周期與內(nèi)存管理機制

一腹缩、類對象的生命周期

什么是類對象的生命周期?
就是從對象創(chuàng)建 ----> 對象使用 ----> 對象銷毀
廢話少說五督,我們直接上代碼來看

class Person(object):
   # 1.可以攔截對象的創(chuàng)建
   def __new__(cls, *args, **kwargs):
        print('__new__方法調(diào)用')
       return super(Person, cls).__new__(cls, *args, **kwargs)

   # 2.創(chuàng)建對象完成后會自動調(diào)用這個方法,并把實例傳遞給init方法
    def __init__(self):
       print('__init__初始化方法')
       self.name = 'zb'

   # 3.對象釋放的時候自動調(diào)用
   def __del__(self):
       print('__del__對象釋放')
 
  p = Person()  # 創(chuàng)建對象
  del p      # 刪除對象

結(jié)果輸出

__new__方法調(diào)用
__init__初始化方法
 __del__對象釋放

由此可見
創(chuàng)建對象時候先后調(diào)用new --> init
刪除對象的時候 調(diào)用del

二、內(nèi)存管理機制:

介紹內(nèi)存管理之前我們先熟悉幾個函數(shù)煌张,之后我們會用到

 print(id(p))   # 打印內(nèi)存地址 10進制
 print(hex(id(p)))  # 打印內(nèi)存地址 16進制
 print(sys.getrefcount(p))  #查看對象的引用計數(shù)器的值

python 是萬物皆對象,所有基本數(shù)據(jù)類型都是對象退客,但是常用數(shù)據(jù)類型的對象地址相同

 num1 = 2
 num2 = 2
 print(hex(id(num1)), hex(id(num2)))
 結(jié)果:0x1097fd070     0x1097fd070

內(nèi)存管理包括2個機制并存引用計數(shù)器機制(性能高) + 垃圾回收機制(性能低骏融,但是能解決循環(huán)引用問題)

2.1 引用計數(shù)器:計算對象被引用的次數(shù)是+1 取消引用-1

 import sys
class Person(object):
      pass
 p1 = Person()  # 引用計數(shù)器 = 1
 print(sys.getrefcount(p1))

 p2 = p1      # 引用計數(shù)器 = 2
 print(sys.getrefcount(p1))

 del p1    # 引用計數(shù)器 = 1

 del p2    # 引用計數(shù)器 = 1
 
//  結(jié)果:2
         3

注意:sys.getrefcount(p1)函數(shù)會自動將p1的引用計數(shù)器+ 1, 所以計算的時候要-1 引用計數(shù) 0 表示對象會被銷毀

2.1.1 引用計數(shù)器+1 4個場景
A. 創(chuàng)建對象的時候 + 1萌狂; p = Person();
B . 對象賦值的時候 + 1档玻; p2 = p
C. 對象作為函數(shù)的參數(shù) + 2; func(p) 函數(shù)里面有2個引用
D. 對象作為某個對象的容器對象 + 1 茫藏; a = [p]

2.1.2 引用計數(shù)器-1 4個場景
A. 對象被刪除 -1; del p
B. 對象被重新賦值 -1误趴; p = 123
C. 函數(shù)執(zhí)行完畢,離開作用域-1务傲;
D. 針對對象的容器對象的銷毀 -1; del a

2.2 垃圾回收機制
引用計數(shù)機制雖然可以管理內(nèi)存凉当,但是不能解決循環(huán)引用問題碧囊,于是引用垃圾回收機制

  objgraph.count('Person')   # 查看類對象引用個數(shù)

垃圾回收機制底層原理

  # 1、收集所有的"容器對象"(列表纤怒、字典糯而、元祖、自定義對象)泊窘,通過雙向鏈表(集合)進行引用
  # 2熄驼、針對每一個"容器對象",通過一個變量gc_refs來記錄當(dāng)前的引用計數(shù)器
  # 3烘豹、對象每個'容器對象'瓜贾,找到他引用的'容器對象',并將這個'容器對象'的引用計數(shù)器 -1
  # 4携悯、經(jīng)過步驟3之后祭芦,如果一個'容器對象'的引用計數(shù)器未0 就代表這個東西可以被回收啦,肯定是循環(huán)引用導(dǎo)致的

垃圾回收機制底層優(yōu)化:分代回收 (優(yōu)化垃圾回收性能)

垃圾檢測觸發(fā)機制:垃圾回收器 新增的對象個數(shù) - 消亡的對象 達到一定的閾值才會觸發(fā)垃圾回收

   # 閾值設(shè)置
  import gc
  print(gc.get_threshold())
   # (700, 10, 10)  默認當(dāng)閾值大于700 檢測一次   大于10 1代檢測   大于10 2代加測
  # 設(shè)置垃圾檢測
  gc.set_threshold(1000, 5, 5)

2.2.1 垃圾回收觸發(fā)時機
A. 自動觸發(fā) : 先開啟機制 后設(shè)置閾值

 import gc
# 判斷是否開啟垃圾回收
isenable = gc.isenabled()
if isenable == False:
      # 1. 開啟回收
      gc.enable() 
#設(shè)置閾值
gc.set_threshold(500, 10, 10)

B.手動觸發(fā) : 解決循環(huán)引用

import objgraph   # 引用計數(shù)器count
import gc         # 垃圾回收機制
import weakref    # 弱引用
class Person(object):
    def __del__(self):   // 實現(xiàn)了del 不能自動回收
          print('Person對象被釋放啦')

class Dog(object):
      def __del__(self):
          print('Dog對象被釋放啦')

p = Person()
d = Dog()
# 循環(huán)引用
p.pet = d
d.master = p
 # d.master = weakref.ref(p)  #解決循環(huán)引用方式一 弱引用的應(yīng)用
# p.pet = None     # 解決循環(huán)引用方式二 指向None
del p
del d
# 解決循環(huán)引用方式三 垃圾回收機制手動回收
# gc.collect(1)
print(objgraph.count('Person'))
print(objgraph.count('Dog'))

總結(jié)

解決循環(huán)引用方案 :

1憔鬼、weakref 弱引用 - 一個對象的弱引用 一對多的引用用需要弱引用字典
2龟劲、指向None 置空對象
3、 gc.collect(1) 垃圾回收機制回收

最后贈言

學(xué)無止境轴或,學(xué)習(xí)Python的伙伴可以多多交流昌跌。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市照雁,隨后出現(xiàn)的幾起案子蚕愤,更是在濱河造成了極大的恐慌,老刑警劉巖饺蚊,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件萍诱,死亡現(xiàn)場離奇詭異,居然都是意外死亡污呼,警方通過查閱死者的電腦和手機裕坊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來曙求,“玉大人碍庵,你說我怎么就攤上這事映企∥蛴” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵堰氓,是天一觀的道長挤渐。 經(jīng)常有香客問我,道長双絮,這世上最難降的妖魔是什么浴麻? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任得问,我火速辦了婚禮,結(jié)果婚禮上软免,老公的妹妹穿的比我還像新娘宫纬。我一直安慰自己,他們只是感情好膏萧,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布漓骚。 她就那樣靜靜地躺著,像睡著了一般榛泛。 火紅的嫁衣襯著肌膚如雪蝌蹂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天曹锨,我揣著相機與錄音孤个,去河邊找鬼。 笑死沛简,一個胖子當(dāng)著我的面吹牛齐鲤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播椒楣,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼佳遂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了撒顿?” 一聲冷哼從身側(cè)響起丑罪,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凤壁,沒想到半個月后吩屹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡拧抖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年煤搜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唧席。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡擦盾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出淌哟,到底是詐尸還是另有隱情迹卢,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布徒仓,位于F島的核電站腐碱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏掉弛。R本人自食惡果不足惜症见,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一喂走、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谋作,春花似錦芋肠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谬晕,卻和暖如春碘裕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背攒钳。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工帮孔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人不撑。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓文兢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親焕檬。 傳聞我的和親對象是個殘疾皇子姆坚,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 生命周期的概念:世界上的萬事萬物都有它的生命周期,那么針對對象的生命周期到底是從哪里開始從哪里結(jié)束呢实愚?當(dāng)我們創(chuàng)建一...
    hello_我的哥閱讀 7,667評論 0 5
  • python內(nèi)存管理是通過引用計數(shù)來實現(xiàn)的兼呵。當(dāng)對象的引用計數(shù)為0時,會被gc回收腊敲。 為了探索對象在內(nèi)存的存儲击喂,我們...
    冬季戀歌1218閱讀 1,643評論 0 2
  • 1.元類 1.1.1類也是對象 在大多數(shù)編程語言中,類就是一組用來描述如何生成一個對象的代碼段碰辅。在Python中這...
    TENG書閱讀 1,253評論 0 3
  • [TOC] 內(nèi)存管理 一懂昂、托管堆基礎(chǔ) 在面向?qū)ο笾校總€類型代表一種可使用的資源没宾,要使用該資源凌彬,必須為代表資源的類...
    _秦同學(xué)_閱讀 3,778評論 0 3
  • 我還是長大了。 我還是只能把你留下來循衰。 我們彼此相似铲敛,我們彼此又不同。 我走你走過的路羹蚣,卻會選擇一種你也許沒有嘗試...
    lemo_8b6a閱讀 218評論 1 0