天天看點

Python記憶體管理機制

1 概述

對于python這樣的動态語言,如何高效的管理記憶體,是很重要的一部分,在很大程度上決定了python的執行效率。與大多數程式設計語言不同,python中的變量無需事先申明,變量無需指定類型,程式員無需關心記憶體管理,python解釋器給你自動回收。我們知道在變量配置設定記憶體時,是借用系統資源,在使用完成後,應該歸還所借用的系統資源,python承擔了這個複雜的記憶體管理工作,進而讓程式員更加的關注程式的編寫品質上。

在執行過程中,python會頻繁的建立和銷毀大量的對象,這些都涉及到記憶體的管理。以下從三個方面來分析python是如何進行記憶體管理的。

2 對象的引用計數機制

在python中是通過引用計數來保持對記憶體中的變量追蹤的,也就是做python内部記錄中所有在使用對象各有多少個引用。python中有個内部跟蹤變量叫做引用計數器,每個變量有多少個引用,簡稱引用計數。當某個對象的引用計數為0時,就列入了垃圾回收隊列。

引用計數增加的情況:

1. 一個對象配置設定一個新名稱

2. 将其放入一個容器中(如清單、元組或字典)

引用計數減少的情況:

1. 使用del語句對對象别名顯式的銷毀

2. 引用超出作用域或被重新指派

sys.getrefcount( )函數可以獲得對象的目前引用計數

多數情況下,引用計數比你猜測得要大得多。對于不可變資料(如數字和字元串),解釋器會在程式的不同部分共享記憶體,以便節約記憶體。

3 垃圾回收機制

3.1 當一個對象的引用計數歸零時,與該對象對應的析構函數就會被調用,但調用析構函數并不意味着最終一定要調用free釋放記憶體空間,通常是将該對象通過垃圾收集機制處理,将其占用的空間歸還到記憶體池中。

3.2 當兩個對象a和b互相引用時,del語句可以減少a和b的引用計數,并銷毀用于引用底層對象的名稱。然而由于每個對象都包含一個對其他對象的應用,是以引用計數不會歸零,對象也不會銷毀。(進而導緻記憶體洩露)。為解決這一問題,解釋器會定期執行一個循環檢測器,搜尋不可通路對象的循環并删除它們。

4 記憶體池機制

python提供了對記憶體的垃圾回收機制,但是它将不用的記憶體放到記憶體池而不是傳回給作業系統。

4.1 小塊記憶體池機制pymalloc機制

在python中,許多時候申請的記憶體都是小塊的記憶體,這些小塊記憶體在申請後,很快又會被釋放,由于這些記憶體的申請并不是為了建立對象,是以并沒有對象一級的記憶體池機制。這就意味着在運作期間,python會大量的執行malloc和free操作。為了加速python的執行效率,python引入了一個記憶體池機制,用于管理對小塊記憶體的申請和釋放,即pymalloc機制。

1. 當申請的記憶體小于256位元組時,pyobject_malloc會在記憶體池中申請記憶體;當申請的記憶體大于256位元組時,pyobject_malloc的行為将蛻化為malloc的行為。當然,通過修改python源代碼,我們可以改變這個預設值,進而改變python的預設記憶體管理行為。

2. 對于python對象,如整數,浮點數和list,都有其獨立的私有記憶體池,對象間不共享他們的記憶體池。也就是說如果你配置設定又釋放了大量的整數,用于緩存這些整數的記憶體就不能再配置設定給浮點數。

                                                                                                                               ——遊響雲停

本文出自 “” 部落格,請務必保留此出處