Python記憶體管理機制

來源:互聯網
上載者:User

標籤:需要   工作   list   idp   源碼   賦值   分享   允許   有一個   

說到記憶體管理,就先說一下記憶體回收吧。記憶體回收是Python,Java等語言管理記憶體的一種方式,說的直白些,就是清除無用的垃圾對象。C語言及C++中,需要通過malloc來進行記憶體的申請,通過free而進行記憶體的釋放。而Python和Java中有自動的記憶體管理機制,不需要動態釋放記憶體,這種機制就是記憶體回收。

 

Python中通過引用計數法來進行記憶體的管理的。對每一個對象,都維護這一個對指向該對對象的引用的計數。比如:

 

a = "ABC"
b = a

 

首先建立了一個字串對象"ABC",然後將字串對象的引用賦值為a。因而,字串對象"ABC"的引用計數會加1。當執行b=a的時候,僅僅是建立了指向"ABC"這個字串對象的引用的別名,而沒有建立對象。這樣,字串對象"ABC"的引用計數會加1。如何驗證呢?我們可以查看a和b的id是否一致即可:

 

a = "ABC"
b = a
id(a) 36422672
id(b) 36422672

 

引用計數的數目可以通過sys.getrefcount()函數來進行擷取。為啥建立a對象後引用計數是2而不是1呢?這是因為一個是全域域裡的,一個是調用函數的。當執行完b=a後,引用計數加1。

 

import sys
a = "ABC"
sys.getrefcount(a) 2
b = a
sys.getrefcount(a) 3

 

那什麼時候引用計數增加,什麼時候引用計數減少呢?小編總結了一下:

 

引用計數增加主要有以下情境:

1、對象被建立時:a = "ABC";

2、另外的別人被建立時:b = a;

3、被作為參數傳遞給函數時:foo(a);

4、作為容器物件(list,元組,字典等)的一個元素時:x = [1,a,‘33‘]。

引用計數減少主要有以下情境:

1、一個本地引用離開了它的範圍時,比如上面的foo(a)函數結束時,a指向的對象引用減1;

2、對象的引用被顯式的銷毀時:del a 或者 del b;

3、對象的引用被賦值給其他對象時:a = 789;

4、對象從一個容器物件(例如list)中移除時:L.remove(a);

5、容器物件本身被銷毀:del L,或者容器物件本身離開了範圍。

 

所謂記憶體回收,就是回收引用計數為0的對象,釋放其佔用的記憶體空間。記憶體回收機制還有一個迴圈記憶體回收行程, 確保釋放循環參考對象(a引用b, b引用a, 導致其引用計數永遠不為0)。

 

Python的記憶體管理是階層的,各層負責不同的功能,如所示:-1,-2層主要有作業系統進行操作,屬於核心態;第0層是C中的malloc,free等記憶體配置和釋放函數進行操作;第1層和第2層是記憶體池,有Python的介面函數PyMem_Malloc函數實現,當對象小於256K時由該層直接分配記憶體;第3層是最上層,也就是我們對Python對象的直接操作。感興趣的同學可以閱讀以下《Python源碼剖析》,相信你的收穫肯定是大大滴。

 

 

在 C 中如果頻繁的調用 malloc 與 free 時會產生效能問題的,再加上頻繁的分配與釋放小塊的記憶體會產生記憶體片段。Python 在這裡主要乾的工作有:如果請求分配的記憶體在1~256位元組之間就使用自己的記憶體管理系統,否則直接使用 malloc。這裡還是會調用 malloc 分配記憶體,但每次會分配一塊大小為256k的大塊記憶體。經由記憶體池登記的記憶體到最後還是會回收到記憶體池,,並不會調用 C 的 free 釋放掉,以便下次使用。

 

Python中的變數在記憶體中的分配主要有兩種,一種是簡單拷貝,比如上一篇講述的list,改變一個就會引起另一個的改變,這是因為它們的引用相同,指向了同一個對象:

 

L= [3,4,5]
LL = L
id(L)  34432584
id(LL) 34432584
L.append(6)
id(L)  34432584
id(LL) 34432584

 

另外一種是深度拷貝,如數值、字串、元組(tuple不允許被更改)等,也就是說當將變數a賦值給變數b時,雖然a和b的記憶體空間仍然相同,但當a的值發生變化時,會重新給a分配空間,a和b的地址變得不再相同。

 

a = ‘ABC‘
b = a
id(a) 36042680
id(b) 36042680
a = ‘XYZ‘
id(a) 36043424
id(b) 36042680

Python記憶體管理機制

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.