整數在程序中的使用很是普遍,Python爲了優化速度,使用了小整數對象池, 避免爲整數頻繁申請和銷燬內存空間。java
Python 對小整數的定義是 [-5, 257) 這些整數對象是提早創建好的,不會被垃圾回收。在一個 Python 的程序中,全部位於這個範圍內的整數使用的都是同一個對象.python
同理,單個字母也是這樣的。app
可是當定義2個相同的字符串時,引用計數爲0,觸發垃圾回收函數
每個大整數,均建立一個新的對象。優化
python靠引用計數去維護什麼時候釋放內存spa
python裏也同java同樣採用了垃圾收集機制,不過不同的是: python採用的是引用計數機制爲主,標記-清除和分代收集兩種機制爲輔的策略操作系統
引用計數機制:debug
python裏每個東西都是對象,它們的核心就是一個結構體:PyObject
日誌
typedef struct_object { int ob_refcnt; struct_typeobject *ob_type; } PyObject;
PyObject是每一個對象必有的內容,其中ob_refcnt就是作爲引用計數。當一個對象有新的引用時,它的ob_refcnt就會增長,當引用它的對象被刪除,它的ob_refcnt就會減小;當引用計數爲0時,該對象生命就結束了。 code
list1 = [] list2 = [] list1.append(list2) list2.append(list1)
ist1與list2相互引用,若是不存在其餘對象對它們的引用,list1與list2的引用計數也仍然爲1,所佔用的內存永遠沒法被回收,這將是致命的。 對於現在的強大硬件,缺點1尚可接受,可是循環引用致使內存泄露,註定python還將引入新的回收機制。(標記清除和分代收集)
GC系統所承擔的工做遠比"垃圾回收"多得多。實際上,它們負責三個重要任務。它們
爲新生成的對象分配內存
識別那些垃圾對象,而且
從垃圾對象那回收內存。
當建立對象時,python當即向操做系統請求內存
中止程序,加標記,把未被標記的對象看成垃圾處理
對象被建立,例如a=23
對象被引用,例如b=a
對象被做爲參數,傳入到一個函數中,例如func(a)
對象做爲一個元素,存儲在容器中,例如list1=[a,a]
對象的別名被顯式銷燬,例如del a
對象的別名被賦予新的對象,例如a=24
一個對象離開它的做用域,例如f函數執行完畢時,func函數中的局部變量(全局變量不會)
對象所在的容器被銷燬,或從容器中刪除對象
import sys y='hh' print(sys.getrefcount(y))
import gc class ClassA(): def __init__(self): print('object born,id:%s'%str(hex(id(self)))) def f2(): while True: c1 = ClassA() c2 = ClassA() c1.t = c2 c2.t = c1 del c1 del c2 #把python的gc關閉 gc.disable() f2()
執行f2(),進程佔用的內存會不斷增大。
c1.t=c2
和c2.t=c1
後,這兩塊內存的引用計數變成2.1).import gc
gc.get_threshold()
輸出:(700,10,10) (當沒有釋放的對象個數超過700,即開始0級垃圾回收,0級垃圾回收超過10次即開始1級垃圾回收,1級垃圾回收清除包括0級垃圾,1級垃圾回收超過10次,即開始2級垃圾回收,2級垃圾回收清除包括0級,1級垃圾)
2).垃圾回收機制python默認開啓的,gc.disabled可關閉垃圾回收機制,當程序完成時,垃圾最後仍被回收
3).當gc.disabled時,gc.collect手動開啓垃圾回收機制
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的列表