python10_內存管理

1)python動態類型:
對象是儲存在內存中的實體
在程序中寫的對象名只是指向這一對象的引用
引用和對象分離,是動態類型的核心
引用能夠隨時指向新的對象(內存地址會不同)python

2)引用計數:在python中,每一個對象都有存有指向該對象的引用總數,即引用計數
原理:每一個對象維護一個 ob_ref 字段,用來記錄該對象當前被引用的次數
每當新的引用指向該對象時,它的引用計數ob_ref加1
每當該對象的引用失效時計數ob_ref減1
一旦對象的引用計數爲0,該對象能夠被回收,對象佔用的內存空間將被釋放
缺點:須要額外的空間維護引用計數,這個問題是其次的-------最主要的問題是它不能解決對象的「循環引用」編程

獲取引用計數:getrefcount()
python10_內存管理
當使用某個引用做爲參數,傳遞給getrefcount()時,參數實際上建立了一個臨時的引用。所以, getrefcount()所獲得的結果,會比指望的多1。緩存

增長引用計數:當一個對象A被另外一個對象B引用時,A的計數會+1
python10_內存管理app

減小引用計數:del刪除或從新引用時,引用計數會變化(del只是刪除引用)
python10_內存管理編程語言

循環引用:
x = []
y = []
x.append(y)
y.append(x)
對於上面相互引用的狀況,若是不存在其餘對象對他們的引用,這兩個對象 所佔用的內存也仍是沒法回收,從而致使內存泄漏ide

引用計數機制的優勢:簡單,實時性
引用計數機制的缺點:維護引用計數消耗資源;循環引用時沒法回收對象

3)垃圾回收
回收原則:當python某個對象的引用計數降爲0時,可被垃圾回收
gc機制:
GC做爲現代編程語言的自動內存管理機制,專一於兩件事
找到內存中無用的垃圾資源
清除這些垃圾並把內存讓出來給其餘對象使用blog

效率問題:垃圾回收時,Python不能進行其它的任務。頻繁的垃圾回收將大大下降Python的工做效率。
當Python運行時,會記錄其中分配對象(object allocation)和取消分配對象(object deallocation)的 次數。當二者的差值高於某個閾值時,垃圾回收纔會啓動。
python10_內存管理
三種狀況觸發垃圾回收:
調用gc.collect()
GC達到閾值時
程序退出時遞歸

分代回收:這一策略的基本假設是:存活時間越久的對象,越不可能在後面的程序中變成垃圾
Python將全部的對象分爲0,1,2三代
全部的新建對象都是0代對象。
當某一代對象經歷過垃圾回收,依然存活,那麼它就被納入下一代對象
垃圾回收啓動時,必定會掃描全部的0代對象
若是0代通過必定次數垃圾回收,那麼就啓動對0代和1代的掃描清理
當1代也經歷了必定次數的垃圾回收後,那麼會啓動對0,1,2,即對全部對象進行掃描ip

標記清除機制:首先標記對象(垃圾檢測),而後清除垃圾(垃圾回收)
主要用於解決循環引用
1.標記:活動(有被引用),非活動(可被刪除)
2.清除:清除全部非活動對象

4)緩衝池
整數對象緩衝池:對於[-5,256] 這樣的小整數,系統已經初始化好,能夠直接拿來用。而對於其餘的大整數,系統則提 前申請了一塊內存空間,等須要的時候在這上面建立大整數對象。
[-5,256]它們的ip地址都是同一個,其餘的不同
字符串緩存:爲了檢驗兩個引用指向同一個對象,咱們能夠用is關鍵字。is用於判斷兩個引用所指的對象是否相同。 當觸發緩存機制時,只是創造了新的引用,而不是對象自己。

字符串的intern機制:python對於短小的,只含有字母數字的字符串自動觸發緩存機制。其餘狀況不會緩存。

5)深拷貝和淺拷貝
數字拷貝:python10_內存管理
多個引用指向同一個對象,若是一個引用值發生變化,那麼其實是讓這個引用指向一個新的引用, 並不影響其餘的引用的指向。

字典拷貝:python10_內存管理
字典淺拷貝:拷貝第一層數據(地址)
python10_內存管理
如今a,b的內存地址是不同的,b只能拷貝到a的第一層地址
字典深拷貝:遞歸拷貝全部層數據
python10_內存管理
通常而言,除了copy.deepcopy,其餘都是淺拷貝,除了一些推導式如:x = [ [] for i in range(3) ]這個是深~
ps:直接賦值不屬於拷貝

數字和字符串、元組,不能改變對象自己,只能改變引用的指向,稱爲不可變數據對象列表、字典、集合能夠經過引用其元素,改變對象自身(in-place change)。這種對象類型,稱爲可 變數據對象

相關文章
相關標籤/搜索