日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python3学习笔记_F(垃圾回收)

發布時間:2023/12/31 python 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python3学习笔记_F(垃圾回收) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

      • 建議不要光看,要多動手敲代碼。眼過千遭,不如手讀一遍。
      • 垃圾回收
        • 代碼塊
        • 代碼塊的緩存機制
        • 小數據池
        • 指定駐留
        • 引用計數
          • GC模塊

筆記中代碼均可運行在Jupyter NoteBook下(實際上Jupyter-lab使用體驗也很棒)。

建議不要光看,要多動手敲代碼。眼過千遭,不如手讀一遍。

相關筆記的jupiter運行代碼已經上傳,請在資源中自行下載。

垃圾回收

參考網址:https://www.cnblogs.com/jin-xin/articles/9439483.html

概括:

同一代碼塊下:緩存機制 不同代碼塊:小數據池

代碼塊

一個模塊、一個函數、一個類、一個文件都是一個代碼塊。

在交互式命令行下,一個命令就是一個代碼塊。

代碼塊的緩存機制

Python在執行同一個代碼塊的初始化對象的命令時,

會檢查是否其值是否已經存在,如果存在,會將其重用。

換句話說:

執行同一個代碼塊時,遇到初始化對象的命令時,他會將初始化的這個變量與值存儲在一個字典中,在遇到新的變量時,會先在字典中查詢記錄,如果有同樣的記錄那么它會重復使用這個字典中的之前的這個值。

滿足緩存機制則他們在內存中只存在一個,即:id相同。

代碼塊的緩存機制的適用范圍: int(float),str,bool。

int(float):任何數字在同一代碼塊下都會復用。bool:True和False在字典中會以1,0方式存在,并且復用。str:幾乎所有的字符串都會符合緩存機制1,非乘法得到的字符串都滿足代碼塊的緩存機制2,乘法得到的字符串分兩種情況:2.1 乘數為1時,任何字符串滿足代碼塊的緩存機制:2.2 乘數>=2時:僅含大小寫字母,數字,下劃線,總長度<=20,滿足代碼塊的緩存機制

優點:

能夠提高一些字符串,整數處理人物在時間和空間上的性能; 需要值相同的字符串,整數的時候,直接從‘字典’中取出復用,避免頻繁創建和銷毀,提升效率,節約內存。 '''jupyter這里運行存在問題,以注釋為主'''# 字符串緩存機制 例子# 非乘法得到的字符串 def unMult():s1 = 'string's2 = 'string'print('非乘法得到的字符串')print('*'*30)print('s1和s2地址比較:',id(s1) == id(s2)) # Trueprint('*'*30)# 乘數為1得到的字符串 def multOne():s3 = 'asdf!@#$%^*'*1s4 = 'asdf!@#$%^*'*1print('乘數為1得到的字符串')print('*'*30)print('s3和s4地址比較:',id(s3) == id(s4)) # Trueprint('*'*30)# 乘數>=2時 def multMore():s3 = 'adf!'*4 # 包含其他字符,總長<20s4 = 'adf!'*4s5 = 'qwertyuiop[]asdfghjk!@#$%^&'*4# 包含其他字符,總長>20s6 = 'qwertyuiop[]asdfghjk!@#$%^&'*4s7 = 'asdf_asdf'*3 # # 不包含其他字符,總長<20s8 = 'asdf_asdf'*3print('乘數為>=2,總長度<=20,包含其他字符得到的字符串')print('*'*30)print('s3和s4地址比較:',id(s3) == id(s4)) # Falseprint('*'*30)print('乘數為>=2,總長度>20,包含其他字符得到的字符串')print('*'*30)print('s5和s6地址比較:',id(s5) == id(s6)) # Falseprint('*'*30)print('乘數為>=2,總長度<=20,不包含其他字符得到的字符串')print('*'*30)print('s7和s8地址比較:',id(s7) == id(s8)) # Trueprint('*'*30)# test unMult() multOne() multMore() 非乘法得到的字符串 ****************************** s1和s2地址比較: True s1和s2來源比較: True ****************************** 乘數為1得到的字符串 ****************************** s3和s4地址比較: True s3和s4來源比較: True ****************************** 乘數為>=2,總長度<=20,包含其他字符得到的字符串 ****************************** s3和s4地址比較: True s3和s4來源比較: True ****************************** 乘數為>=2,總長度>20,包含其他字符得到的字符串 ****************************** s5和s6地址比較: True s5和s6來源比較: True ****************************** 乘數為>=2,總長度<=20,不包含其他字符得到的字符串 ****************************** s7和s8地址比較: True s7和s8來源比較: True ******************************

小數據池

大前提:

小數據池也是只針對 int(float),str,bool。小數據池是針對不同代碼塊之間的緩存機制!!!

Python自動將-5~256的整數進行了緩存,

當你將這些整數賦值給變量時,并不會重新創建對象,

而是使用已經創建好的緩存對象。

python會將一定規則的字符串在字符串駐留池中創建一份。

'''小數據池例子'''# 整數 a = 100 b = 100 c = 123456 d = 123456print('id(a) == id(b): ',id(a) == id(b)) print('id(c) == id(d): ',id(c) == id(d)) id(a) == id(b): True id(c) == id(d): False

指定駐留

# 指定駐留 例子 from sys import interna = 'asd*&'*3 b = 'asd*&'*3print('未指定駐留:a is b:', a is b) print(id(a)) print(id(b))c = intern('asd*&'*3) d = intern('asd*&'*3)print('指定駐留:c is d:', c is d) print(id(c)) print(id(d)) 未指定駐留:a is b: False 139839647396976 139839643255088 不未指定駐留:c is d: True 139839642805680 139839642805680

引用計數

Python中以引用計數為主:

引用計數優點:簡單,實時性引用計數缺點:維護時占用內存,循環引用,造成內存泄漏引用計數減一不止del,還可以透過賦值None

隔代回收

Ruby中的垃圾回收是標記清除,對內存的申請是一次申請多個, 當內存不夠用時再清理,而Python中的內存申請是用一個申請一個。

隔代回收為輔:

零代鏈表中檢測到相互循環引用的減一,得到是否是垃圾(引用計數為0),需要回收,否則不會減一
GC模塊
''' gc.get_count():獲取當前自動執行垃圾回收的計數器返回一個元組(x,y,z) 參數解釋: [ x 表示內存占用, y 表示零代清理次數, z 同理表示1代清理次數 ]gc.get_threshold() 獲取的gc模塊中自動執行垃圾回收的頻率返回(x,y,z) 參數解釋: [ x表示清理上限, y表示每清理零代鏈表10次, 清理一次 1 代鏈表。 z同理是1,2代 這里的x,y,z默認值為(700,10,10) ]查看一個對象的引用計數:sys.getrefcount()gc.disable() 關閉Python的gcgc.enable() 開啟gcgc.isenabled() 判斷是否是開啟gc的gc.collect([generation])顯式進行垃圾回收(手動回收)可以輸入參數: [ 0代表只檢查第一代的對象,1代表檢查一,二代的對象,2代表檢查一,二,三代的對象, 如果不傳參數,執行一個full collection,也就是等于傳2。 ]注意: 盡量不要手動重寫對象的__del__方法, 因為重寫后會使刪除時不會自動調用gc來刪除, 此時需要調用父類的__del__()來刪除 '''# gc 引用計數 示例 import gc, sysa = 1 get_a_c = sys.getrefcount(a) b = a get_b_c = sys.getrefcount(a)gc_c = gc.get_count() gc_t = gc.get_threshold()gc.disable() gc.enable()gc_is = gc.isenabled()gc_cl = gc.collect(2)print(get_a_c, get_b_c, gc_c, gc_t, gc_is, gc_cl) 2275 2275 (603, 5, 0) (700, 10, 10) True 921

總結

以上是生活随笔為你收集整理的Python3学习笔记_F(垃圾回收)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。