1. 程式人生 > >python 記憶體管理機制和調優手段詳解

python 記憶體管理機制和調優手段詳解

今天和大家探討一下Python記憶體管理機制和調優手段.話不多說,直接上乾貨:

那麼Python的記憶體管理機制都有什麼呢?

               1 . 引用計數

                2 . 垃圾回收

                3 . 記憶體池

調優手段也都三大金剛:

                1. 手動垃圾回收

                 2. 調高垃圾回收閾值

                 3. 避免迴圈引用

好啦,現在開始開車了,大家坐穩啦!

垃圾回收機制引用計數在最基礎也是最常見的,為什麼呢?

引用計數:

          引用計數是一種非常高效的記憶體管理手段,當一個Python物件被引用時其引用計數增加1,當其不再被一個變數引用時則計數

減一,當引用計數為0時物件被刪除.

垃圾回收也是有三大幹將的,他們就是引用計數,標記清除, 分代回收.

1. 引用計數:

                 引用計數也是一種垃圾收集機制,而且也是一種最直觀,最簡單的垃圾收集計數.當Python的某個物件的引用計數降為0

時,說明沒有任何引用指向該物件,該物件就成為要被回收的的垃圾了.比如某個新建物件,它被分配給某個引用,物件的引用計數變為

1.如果引用被刪除,物件的引用計數為0,那麼該物件就可以被垃圾回收.不過如果出現迴圈引用的話,引用計數機制就不再起有效的

作用了.

2. 標記清除:

                  引用計數也是一種垃圾收集機制,而且也是一種最直觀,最簡單的垃圾收集計數.當Python的某個物件的引用計數降為0

時,說明沒有任何引用指向該物件,該物件就成為要被回收的的垃圾了.比如某個新建物件,它被分配給某個引用,物件的引用計數變

為 1.如果引用被刪除,物件的引用計數為0,那麼該物件就可以被垃圾回收.不過如果出現迴圈引用的話,引用計數機制就不再起有效

的作用了.

3. 分代回收:

                   從前面"標記-清除"這樣的垃圾收集機制來看,這種垃圾收集機制所帶來的額外操作實際上與系統中總的記憶體塊的數量

是相關的,當需要回收的記憶體塊越多時,垃圾檢測帶來的額外操作就越多,而垃圾回收待來的額外操作就少;反之,當需回收的記憶體塊越

少時,垃圾檢測就將比垃圾回收帶來更少的額外操作.

舉個例子:

             當某些記憶體塊M經過了3次垃圾收集的清洗之後還存活時, 我們就將記憶體塊M劃到一個集合A中去, 而新分配的記憶體都劃分

到集合B中去.當垃圾回收開始工作時,大多數情況都只對集合B進行垃圾回收,而對集合A進行垃圾回收要隔相當長一段時間後才進

行, 這就使得垃圾收集機制需要處理的記憶體少了, 效率自然就提高了.在這麼過程中,集合B中的某些記憶體塊由於存活時間長而會被轉

移到集合A中, 當然,集合A中實際上也存在一些垃圾,這麼垃圾的回收會因為這種分代的機制而被延遲.

最後再來瞅瞅壓軸大傢伙吧!它就是'記憶體池'!

一提到池的大家都會感覺很高大上吧,池的概念是先開闢好一個空間,提高程式碼的執行效率,不會在執行的時候才拿到記憶體.

那麼現在我們來欣賞一下記憶體池的神祕面紗吧!

             1.python的記憶體機制呈現金字塔形狀,-1, -2層主要有作業系統進行操作;

             2. 第0層是c中的malloc, free 等記憶體分配和釋放函式進行操作

             3.第一層和第二層是記憶體池,有python的介面函式 PyMem_Malloc函式實現, 當物件小於256k時有該層直接分配記憶體;

             4. 第3層是最上層, 也就是我們對Python物件的直接操作

             Python在執行期間會大量的執行malloc 和 free的操作, 頻繁地在使用者態和核心態之間進行切換, 這將嚴重影響Python的執

行效率.為了加速Python的執行效率, Python引入了一個記憶體池機制,用於管理對小塊記憶體的申請和釋放.

             Python內部預設的小塊記憶體與大塊記憶體的分界點定在256個位元組, 當申請的記憶體小於256位元組的時候,PyObject_Malloc會在

記憶體池中申請記憶體;當申請的記憶體大於256位元組時,PyObject_Malloc的行為將蛻變為malloc的行為.當然,通過修改Python原始碼,我

們可以改變這個預設值,從而改變Python的預設記憶體管理行為.