1. 程式人生 > >Python記憶體管理(二 arena和快取池)

Python記憶體管理(二 arena和快取池)

接上文:

2.1  arean

多個pool聚合起來就是arean了,當然它也有預設的大小,一般是256k,包含的poo的個數就是256 / 4 = 64 個

先看下arean:

 struct arena_object {

uptr address;

        block* pool_address;

uint nfreepools;

       uint ntotalpools;

struct pool_header* freepools;

struct arena_object* nextarena;

struct arena_object* prevarena;

};

在概念上其實就是一個結構體:

未使用的arena:arean_object構成的集合會成為一個數組,陣列的首地址有arean來維護,這個陣列就是py中

通用小塊記憶體的記憶體池,另一方面nextarea和prearea是用來連線arean_object來形成連結串列結構的,arena用來

管理一組pool,

與pool管理block是類似的,不同的是,pool_header管理的記憶體是和pool_header連線在一起

的,areana_object和它管理的記憶體卻是分離的,當pool_header被申請時,它所管理的記憶體block集合也會一起

被申請,而areana_object被申請時,pool集合的記憶體卻沒有被申請,也就是在某一時刻,pool和sreana才

會建立聯絡,arean從未使用狀態變為可用狀態,可用狀態和不可用狀態分別維護自己的arena連結串列,未使用

狀態的連結串列是單向連結串列,可用狀態的連結串列是一個雙向連結串列,使用new_arena來申請,這就是那個arena

如同一個完整的pool包含pool_header和blocks,arena也包含 arena_object和arena_object所包含的

pool集合,在建立新的arena時,py會先檢查是否還有未使用狀態的arena,如果有,從中抽取一個,把申請

的記憶體地址賦值給arena的address,申請到的這256k的記憶體大小就是pool的容身之處,,這是arena就

和pool建立了聯絡,脫離了未使用態,py還對申請到的256k的記憶體大小做了處理,使其是邊界對齊的,把pool

集合交給pool_address來管理,實際上所有arena的集合就是小塊記憶體池,但py操作記憶體的最小單元卻是pool

一個arena中的pull總是處於下邊三種狀態中的一種:

1)used狀態:至少有一個pool處於使用狀態,至少一個pool處於未使用狀態,內部維護了一個usedpool陣列

2)full狀態:pool中所有的block都已經被使用完畢

3)empty狀態:pool中所有的block都未被使用,處於這個狀態的pool的集合通過pool_header中的next_pool構成一個連結串列,這個連結串列的表頭就是arena_object中的freepools

注意:full狀態的pool是相互獨立的,並沒有形成連結串列



2.2  緩衝池

       python內部預設小塊記憶體和大塊記憶體的分界點是256k,由small_request_threshold符號控制,也就是,當申請的記憶體大小小於256k時,PyObject_Malloc會在記憶體池中申請記憶體,當申請的記憶體大於256k時,PyObject_Malloc會變成真正的malloc,當然,可以通過修改python的原始碼來修改這個預設值

2.2.1 pool的初始化

      在python啟動的時候,usedpools這個小塊空間記憶體池並不存在可用記憶體,py採用了延遲分配的策略,申請記憶體時才建立這個記憶體池,例如申請28位元組的記憶體大小,py會先在usedpools對應位置查詢,查詢不到任何可用的pool時,py會從unused_arenas中的第一個可用arena獲取一個pool,而如果此時usable_arenas為空的話,py會新申請一個arena

PS: 寫的比較簡略,希望有興趣的讀者去看下Python原始碼剖析這本書,pdf版,you can get :

http://download.csdn.net/detail/njys1/9691736

哈哈~  希望可以幫到大家