超級(jí)好用的C++實(shí)用庫(kù)之動(dòng)態(tài)內(nèi)存池

概述

動(dòng)態(tài)內(nèi)存池是一種內(nèi)存管理技術(shù),主要用于提高程序在頻繁進(jìn)行小塊內(nèi)存分配和釋放時(shí)的效率。相比于傳統(tǒng)的malloc/free、new/delete、或其他動(dòng)態(tài)內(nèi)存分配函數(shù),內(nèi)存池預(yù)先申請(qǐng)一大塊連續(xù)內(nèi)存,并將這塊大內(nèi)存分割成多個(gè)固定大小或一定范圍大小的小內(nèi)存塊,然后以池的方式管理和分發(fā)這些小內(nèi)存塊。
內(nèi)存池一般包括:初始化、分配內(nèi)存塊、回收內(nèi)存塊以及整體釋放等功能模塊。具體實(shí)現(xiàn)時(shí),可以通過(guò)數(shù)組、鏈表或樹(shù)等多種數(shù)據(jù)結(jié)構(gòu)來(lái)組織和追蹤空閑內(nèi)存塊的狀態(tài)。當(dāng)請(qǐng)求分配內(nèi)存時(shí),從池中取出一個(gè)空閑塊。當(dāng)內(nèi)存不再使用時(shí),將其歸還到內(nèi)存池中,以便后續(xù)復(fù)用。

CHP_DynamicMemPool類

在C++中,并沒(méi)有內(nèi)置的內(nèi)存池類。為了方便應(yīng)用層使用內(nèi)存池,我們封裝了CHP_DynamicMemPool類。CHP_DynamicMemPool類是對(duì)動(dòng)態(tài)內(nèi)存池的封裝,適用于需要頻繁使用內(nèi)存塊,內(nèi)存塊的總數(shù)相對(duì)固定,但每個(gè)內(nèi)存塊的大小不一樣的場(chǎng)景,一般會(huì)結(jié)合隊(duì)列使用。CHP_DynamicMemPool類的頭文件,可參考下面的示例代碼。

#pragma once

#include <list>

#include "HP_Mutex.h"

class CHP_DynamicMemPool
{
public:
    CHP_DynamicMemPool();
    ~CHP_DynamicMemPool();

    void Init(unsigned int uiMaxBlockCount, bool bNeedLock = true);

    char *Alloc(unsigned int uiBytes);

    void Release(char *pBuf);

    void Reset();

    unsigned int GetTotalBlockCount();

    void GetCurBlockCount(unsigned int &uiUsedCount, unsigned int &uiFreeCount);

private:
    typedef struct _TDynamicMemBlock 
    {
        char *pBlock;
        unsigned int uiBlockLen;
    }TDynamicMemBlock;

    typedef std::list<TDynamicMemBlock> TDynamicMemBlockList;

    unsigned int m_uiMaxBlockCount;
    bool m_bNeedLock;
    TDynamicMemBlockList m_listUsed;
    TDynamicMemBlockList m_listFree;
    CHP_Mutex m_mutexBlockList;
};

CHP_DynamicMemPool類有6個(gè)公共成員函數(shù),下面逐一進(jìn)行介紹。
Init:初始化內(nèi)存池,內(nèi)存池中含有多個(gè)內(nèi)存塊,每個(gè)內(nèi)存塊的大小可能不一樣。參數(shù)uiMaxBlockCount為內(nèi)存塊的最大個(gè)數(shù),分配內(nèi)存時(shí),如果超過(guò)內(nèi)存塊的最大個(gè)數(shù),則分配失?。粎?shù)bNeedLock表示是否需要加鎖,默認(rèn)值為true,如果應(yīng)用層使用CHP_DynamicMemPool對(duì)象時(shí)已經(jīng)加了鎖,這里可以傳入false。
Alloc:分配指定大小的buffer。內(nèi)存池中含有一個(gè)已使用隊(duì)列和一個(gè)空閑隊(duì)列,分配buffer時(shí),先從空閑隊(duì)列中查找是否有符合條件的內(nèi)存塊。如果有,直接返回該內(nèi)存塊;如果沒(méi)有,則檢查所有內(nèi)存塊的數(shù)量是否超過(guò)內(nèi)存塊的最大個(gè)數(shù)。如果沒(méi)有超過(guò),則新建一個(gè)合適大小的內(nèi)存塊,并加入已使用隊(duì)列中。如果超過(guò),且空閑隊(duì)列非空,則從空閑隊(duì)列取一個(gè)內(nèi)存塊,并重新分配合適大小的內(nèi)存。參數(shù)uiBytes為buffer的大小,單位為字節(jié)。返回非NULL表示成功,否則失敗。
Release:釋放buffer,將其從已使用隊(duì)列放入到空閑隊(duì)列中。參數(shù)pBuf為之前分配的的buffer指針。
Reset:重置內(nèi)存池,會(huì)釋放所有內(nèi)存塊中的內(nèi)存。
GetTotalBlockCount:獲取所有內(nèi)存塊的數(shù)量。
GetCurBlockCount:獲取已使用內(nèi)存塊和空閑內(nèi)存塊的數(shù)量。參數(shù)uiUsedCount為已使用內(nèi)存塊的數(shù)量,參數(shù)uiFreeCount為空閑內(nèi)存塊的數(shù)量。

總結(jié)

動(dòng)態(tài)內(nèi)存池具有如下幾個(gè)優(yōu)點(diǎn)。
減少內(nèi)存碎片:由于內(nèi)存池中分配的是預(yù)設(shè)大小的內(nèi)存塊,所以在多次分配和回收后,不會(huì)像普通動(dòng)態(tài)內(nèi)存那樣產(chǎn)生大量的不連續(xù)的、無(wú)法利用的小內(nèi)存區(qū)域(即:內(nèi)存碎片)。
提高分配速度:內(nèi)存池中的內(nèi)存分配通常采用簡(jiǎn)單的算法,比如:隊(duì)列或者鏈表,來(lái)管理空閑內(nèi)存塊,因此分配和回收的速度比系統(tǒng)調(diào)用快得多。尤其是在多線程環(huán)境下,可以避免因競(jìng)爭(zhēng)而導(dǎo)致的性能下降。
減少系統(tǒng)開(kāi)銷:系統(tǒng)級(jí)的內(nèi)存分配器需要維護(hù)復(fù)雜的空閑內(nèi)存列表并執(zhí)行較為耗時(shí)的操作,而內(nèi)存池只需處理局部問(wèn)題,降低系統(tǒng)調(diào)用次數(shù),提高了效率。
可預(yù)測(cè)性增強(qiáng):在嵌入式系統(tǒng)中,內(nèi)存池能夠提供更可預(yù)測(cè)的內(nèi)存分配行為,有助于滿足系統(tǒng)對(duì)響應(yīng)時(shí)間和確定性的要求。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容