程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> 從Python的源碼來解析Python下的freeblock

從Python的源碼來解析Python下的freeblock

編輯:更多關於編程

       這篇文章主要介紹了從Python的源碼來解析Python下的freeblock,包括內存空間分配等知識,需要的朋友可以參考下

      1 引言

      在python內存管理中,有一個block的概念。它比較類似於SGI次級空間配置器。

      首先申請一塊大的空間(4KB),然後把它切割成一小份(8, 16 一直到512)。

      當有內存申請的請求時候,簡單的流程是:根據大小找到對應的block,然後在freeblock 上給它一份。

      2 問題

      整個過程是一種比較自然的slab分配方式。但當我讀到這段代碼時,卻感到疑惑:

      ?

    1 2 3 4 5 6 7 8 9 static void* _PyObject_Malloc(void* ctx, size_t nbytes) { ... pool->freeblock = (block*)pool + pool->nextoffset;   pool->nextoffset += INDEX2SIZE(size); *(block **)(pool->freeblock) = NULL; // [1] ... }

      freeblock指向空閒的鏈表,為它賦值很好理解。但是為什麼要加上代碼1處那一句!

      對C比較熟悉的童鞋很容易能看出它的作用,它在為*freeblock賦值為NULL。

      但是為什麼要這麼做?

      直到看到內存回收的代碼:

      ?

    1 2 3 4 5 6 7 static void _PyObject_Free(void* ctx, void*p) { ... *(block**)p = lastfree = pool->freeblock; pool->freeblock = (block*)p; ... }

      回想一下SGI次級空間配置,它需要一個鏈表,指向block中可用的小塊。因為這些快,是離散的,只有用指針才能索引它。

      在SGI次級空間配置中,是用一個union,達到了節省空間的目的:有數據時,它存儲著真正的數據;沒有數據時,它就變成指向下一塊可用內存的指針:

      ?

    1 2 3 4 union __Obj { union __Obj* free_list_link; char client_data[]; };

      這樣一想,問題就變得很明顯了。freeblock指向一個鏈表,鏈表的next域就由它自己來索引。

      在_PyObject_Free中,內存p是要被回收的,它應該插在freeblock的鏈表頭,freeblock被更新指向它。同時,p指向原來freeblock指向的內容,這是一個很簡單的鏈表插入操作。

      這樣在遍歷的時候,我們就可以用freeblock = * freeblock的方式來工作了。

      如下圖所示:

    2015511115319124.png (473×154)
    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved