垃圾回收
1. 小整數對象池
整數在程序中的使用很是普遍,Python爲了優化速度,使用了小整數對象池,避免爲整數頻繁申請和銷燬內存空間。python
Python 對小整數的定義是 [-5, 257) 這些整數對象是提早創建好的,不會被垃圾回收。在一個Python 的程序中,全部位於這個範圍內的整數使用的都是同一個對象.函數
同理,單個字母也是這樣的。優化
可是當定義2個相同的字符串時,引用計數爲0,觸發垃圾回收spa
2. 大整數對象池
每個大整數,均建立一個新的對象。debug
In [29]: id(b) Out[29]: 10914368 In [30]: a=1000 In [31]: b=1000 In [32]: id(a) Out[32]: 139681389577584 In [33]: id(b) Out[33]: 139681389577712
3. intern機制日誌
a1 = "HelloWorld" a2 = "HelloWorld" a3 = "HelloWorld" a4 = "HelloWorld" a5 = "HelloWorld" a6 = "HelloWorld" a7 = "HelloWorld" a8 = "HelloWorld" a9 = "HelloWorld"
python會不會建立9個對象呢?在內存中會不會開闢9個」HelloWorld」的內存空間呢? 想一下,若是是這樣的話,咱們寫10000個對象,好比a1=」HelloWorld」…..a1000=」HelloWorld」, 那他豈不是開闢了1000個」HelloWorld」所佔的內存空間了呢?若是真這樣,內存不就爆了嗎?因此python中有這樣一個機制——intern機制,讓他只佔用一個」HelloWorld」所佔的內存空間。靠引用計數去維護什麼時候釋放。code
總結
小整數[-5,257)共用對象,常駐內存
單個字符共用對象,常駐內存
單個單詞,不可修改,默認開啓intern機制,共用對象,引用計數爲0,則銷燬 單詞垃圾回收
字符串(含有空格),不可修改,沒開啓intern機制,不共用對象,引用計數爲0,銷燬
大整數不共用內存,引用計數爲0,銷燬 大整數垃圾回收
數值類型和字符串類型在 Python 中都是不可變的,這意味着你沒法修改這個對象的值,每次對變量的修改,其實是建立一個新的對象不可變對象
循環引用而且關閉gc,內存不斷增長blog
import gc class Test1(object): def __init__(self): print("object born,id:%s"%str(hex(id(self)))) def f2(): while True: c1 = Test1() c2 = Test1() c1.t = c2 c2.t = c1 del c1 del c2 gc.disable() f2()
python採用的是引用計數爲主,隔代回收爲輔的垃圾回收策略接口
GC系統承擔的工做遠比「垃圾回收」多得多。
主要負責三個任務:
一、爲新生成的對象分配內存
二、識別那些垃圾對象
三、從垃圾對象那回收內存
分代回收思想將對象分爲三代(generation 0,1,2),0表明幼年對象,1表明青年對象,2表明老年對象。根據弱代假說(越年輕的對象越容易死掉,老的對象一般會存活更久。)
新生的對象被放入0代,若是該對象在第0代的一次gc垃圾回收中活了下來,那麼它就被放到第1代裏面(它就升級了)。若是第1代裏面的對象在第1代的一次gc垃圾回收中活了下來,它就被放到第2代裏面。gc.set_threshold(threshold0[,threshold1[,threshold2]])設置gc每一代垃圾回收所觸發的閾值。從上一次第0代gc後,若是分配對象的個數減去釋放對象的個數大於threshold0,那麼就會對第0代中的對象進行gc垃圾回收檢查。 從上一次第1代gc後,若是第0代被gc垃圾回收的次數大於threshold1,那麼就會對第1代中的對象進行gc垃圾回收檢查。一樣,從上一次第2代gc後,如過第1代被gc垃圾回收的次數大於threshold2,那麼就會對第2代中的對象進行gc垃圾回收檢查。
gc模塊經常使用功能
gc模塊提供一個接口給開發者設置垃圾回收的選項。上面說到,採用引用計數的方法管理內存的一個缺陷是循環引用,而gc模塊的一個主要功能就是解決循環引用的問題。
###經常使用函數
一、gc.set_debug(flags)
設置gc的debug日誌,通常設置爲gc.DEBUG_LEAK
二、gc.collect([generation]) 顯式進行垃圾回收,能夠輸入參數,0表明只檢查第一代的對象,1表明檢查一,二代的對象,2表明檢查一,二,三代的對象,若是不傳參數,執行一個full collection,也就是等於傳2。 返回不可達(unreachable objects)對象的數目
三、gc.get_threshold() 獲取的gc模塊中自動執行垃圾回收的頻率。
四、gc.set_threshold(threshold0[, threshold1[, threshold2]) 設置自動執行垃圾回收的頻率。
五、gc.get_count() 獲取當前自動執行垃圾回收的計數器,返回一個長度爲3的列表
查看當前分代回收的頻率
In [9]: gc.get_threshold() Out[9]: (700, 10, 10)
一、致使引用計數+1的狀況:
對象被建立,例如a=23
對象被引用,例如b=a
對象被做爲參數,傳入到一個函數中,例如func(a)
對象做爲一個元素,存儲在容器中,例如list=[a,a]
二、致使引用計數-1的狀況:
對象的別名被顯示銷燬,例如del a
對象的別名被賦予新的對象,例如a=24
一個對象離開它的做用域,例如f函數執行完畢時,func函數中的局部變量(全局變量不會改變)
對象所在的容器被銷燬,或從容器中刪除對象
三、查看一個對象的引用計數
In [9]: a = "hello world" In [10]: sys.getrefcount(a) Out[10]: 2