STL原始碼剖析 空間配置器

2021-09-30 13:54:12 字數 1487 閱讀 3096

stl空間配置器:主要分三個檔案實現。

1、stl_construct.h 。 這裡定義了全域性函式construct()和destroy(),負責物件的構造和析構。

2、stl_alloc.h。檔案中定義了

一、二兩級配置器,彼此合作,配置器名為alloc。

3、stl_uninitialized.h。 這裡定義了一些全域性函式,用來填充(fill)或複製(copy)大塊記憶體資料。

在stl_alloc.h中定義了兩級配置器,主要思想是申請大塊記憶體池,小塊記憶體直接從記憶體池中申請,當不夠用時再申請新的記憶體池,還有就是大塊記憶體直接申請

當申請空間大於128位元組時呼叫第一級配置器,第一級配置器沒有用operator::new和operator::delete來申請空間,而是直接呼叫malloc/free和realloc,並且實現了類似c++中new-handler的機制。所謂c++ new handler機制是,你可以要求系統在記憶體配置需求無法被滿足時,呼叫乙個指定的函式。

當申請區塊小於128位元組時,則以記憶體池管理,此法又稱為次層配置,每次配置一大塊記憶體,並維護對應的自由鍊錶(free-list)。下次若再有相同大小的記憶體需求,就直接從free-list中拔出。如果客端釋還小額區塊,就由配置器**到free-lists中,另外,配置器除了負責配置,也負責**。當申請小於等於128位元組時就會檢查對應的free list,如果free-list中有可用的區塊,就直接拿來,如果沒有,就準備為對應的free-list 重新填充空間。新的空間將取自記憶體池,預設取得20個新節點,如果記憶體池不足(還足以乙個以上的節點),就返回的相應的節點數.如果當記憶體池中連乙個節點大小都不夠時,就申請新的記憶體池。

這種做法有兩個優點:

(1)小物件的快速分配。小物件是從記憶體池分配的,這個記憶體池是系統呼叫一次malloc分配一塊足夠大的區域給程式備用,當記憶體池耗盡時再向系統申請一塊新的區域,整個過程類似於批發和零售,起先是由allocator向總經商批發一定量的貨物,然後零售給使用者,與每次都總經商要乙個貨物再零售給使用者的過程相比,顯然是快捷了。當然,這裡的乙個問題時,記憶體池會帶來一些記憶體的浪費,比如當只需分配乙個小物件時,為了這個小物件可能要申請一大塊的記憶體池,但這個浪費還是值得的,況且這種情況在實際應用中也並不多見。

(2)避免了記憶體碎片的生成。程式中的小物件的分配極易造成記憶體碎片,給作業系統的記憶體管理帶來了很大壓力,系統中碎片的增多不但會影響記憶體分配的速度,而且會極大地降低記憶體的利用率。以記憶體池組織小物件的記憶體,從系統的角度看,只是一大塊記憶體池,看不到小物件記憶體的分配和釋放。

注意:

當記憶體塊在鍊錶上時,前4個位元組是用作指向下乙個空閒塊,當分配給使用者時,它是一塊普通的記憶體區。

這個設計太巧妙了!!!

STL原始碼剖析 空間配置器

看過stl空間配置器的原始碼,總結一下 1 stl空間配置器 主要分三個檔案實現,stl construct.h 這裡定義了全域性函式construct 和destroy 負責物件的構造和析構。stl alloc.h檔案中定義了 一 二兩級配置器,彼此合作,配置器名為alloc.stl uninit...

STL原始碼剖析 空間配置器

allocator是空間配置器而不是記憶體配置器,空間不一定是記憶體,也可以是磁碟或其他輔助儲存介質。但sgi stl提供的配置器配置的物件是記憶體。sgi標準的空間配置器,std alloctor sgi定義了乙個符合部分標準,名為alloctor的配置器,效率不高,只把c 的 operator ...

STL原始碼剖析 空間配置器

由於物件的建立分為分配記憶體和呼叫建構函式兩部分,stl allocator使用alloc allocate 來分配記憶體,construct 構造物件。construct 函式只有乙個泛化的版本,destroy 函式有乙個泛化的針對迭代器的版本,destroy aux 根據是否需要呼叫析構函式進行...