1. 程式人生 > >Python學習筆記一:PyIntObject記憶體池機制

Python學習筆記一:PyIntObject記憶體池機制

PyIntObject記憶體池機制

                  -----------------   僅以圖片簡單說明,不會做過多囉嗦

1. 已分配空間無剩餘,新建PyIntObject物件。

        此時建立新的PyIntBlock儲存塊加入物件儲存池,由block_list全域性指標維護(block_list始終指向最新加入的PyIntBlock);其中,新建的PyIntBlock塊內部objects[]形成單鏈表,通過PyIntObject物件中維護型別的指標ob_type串聯,該連結串列通過全域性指標free_list維護(free_list指向objects[]尾部位置,記憶體使用從objects[]尾部開始,注:僅針對未被使用的新加入儲存池的PyIntBlock內部objects[])。如下圖:

 

上述各變數在原始碼中的定義如下:

struct _intblock {
    struct _intblock *next;
    PyIntObject objects[N_INTOBJECTS];
};

typedef struct _intblock PyIntBlock;

static PyIntBlock *block_list = NULL;
static PyIntObject *free_list = NULL;

 

2. 使用中的PyIntBloct塊中有物件被刪除。

       當有物件被刪除時,對應的記憶體空間不會釋放給系統,而是加入free_list連結串列中,待後續重複利用,此時free_list始終指向最新加入連結串列的記憶體起始位置。如下圖:

3. Python定義的小整數物件(預設[-5,257),可通過改變原始碼中巨集定義,重新編譯Python來滿足自己的定義需要)有額外的儲存機制,即全域性的small_ints[]陣列,其定義如下:

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS           257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS           5
#endif
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
/* References to small integers are saved in this array so that they
   can be shared.
   The integers that are saved are those in the range
   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];

#endif

此範圍的整數在Python啟動時進行初始化,儲存於small_ints陣列中,同時也會建立對應的PyIntBlock來儲存一份。建立此範圍的整數物件將直接從陣列中獲取。

4. 結論:PyIntObject記憶體池機制是對已分配的記憶體空間的重複利用,避免大量的底層malloc/free呼叫。

5. 說明:箭頭所指均表示指向對應空間的起始位置;參考原始碼為Python-2.7.11版本

 

        以上內容為本人學習Python原始碼時個人理解,若有偏差地方歡迎大牛們給予指正。歡迎大家參與探討,加深理解!