日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

如何用C++實(shí)現(xiàn)簡單的內(nèi)存池

來源: 責(zé)編: 時(shí)間:2024-05-07 09:10:52 172觀看
導(dǎo)讀內(nèi)存池(Memory Pool)是計(jì)算機(jī)編程中一種重要的內(nèi)存管理技術(shù),它預(yù)先分配一塊較大的內(nèi)存區(qū)域,并將其劃分為多個(gè)大小相等的內(nèi)存塊。這種技術(shù)旨在減少因頻繁申請和釋放小塊內(nèi)存而引發(fā)的性能開銷。下面,我們將結(jié)合代碼,一步步講

內(nèi)存池(Memory Pool)是計(jì)算機(jī)編程中一種重要的內(nèi)存管理技術(shù),它預(yù)先分配一塊較大的內(nèi)存區(qū)域,并將其劃分為多個(gè)大小相等的內(nèi)存塊。這種技術(shù)旨在減少因頻繁申請和釋放小塊內(nèi)存而引發(fā)的性能開銷。下面,我們將結(jié)合代碼,一步步講解如何實(shí)現(xiàn)一個(gè)簡單的內(nèi)存池,并分析其工作原理。F4528資訊網(wǎng)——每日最新資訊28at.com

F4528資訊網(wǎng)——每日最新資訊28at.com

一、內(nèi)存池的基本概念

內(nèi)存池是一種用于動(dòng)態(tài)內(nèi)存分配的技術(shù),其核心思想是空間換時(shí)間。通過預(yù)先分配一大塊內(nèi)存,并將其劃分為多個(gè)小塊,內(nèi)存池能夠快速地為程序提供所需的內(nèi)存,而無需每次都向操作系統(tǒng)申請。這樣可以大大減少內(nèi)存分配和釋放的開銷,提高程序的運(yùn)行效率。F4528資訊網(wǎng)——每日最新資訊28at.com

二、內(nèi)存池的實(shí)現(xiàn)步驟

1. 定義內(nèi)存池類

首先,我們定義一個(gè)名為AdvancedMemoryPool的模板類,它接受一個(gè)類型參數(shù)T和一個(gè)默認(rèn)大小為100的整數(shù)參數(shù)PoolSize。這個(gè)類將用于管理內(nèi)存池的分配和回收。F4528資訊網(wǎng)——每日最新資訊28at.com

template <typename T, size_t PoolSize = 100>class AdvancedMemoryPool {    // ...};

2. 初始化內(nèi)存池

在類的構(gòu)造函數(shù)中,我們調(diào)用expandPool函數(shù)來初始化內(nèi)存池。這個(gè)函數(shù)將分配一塊大小為PoolSize * sizeof(T)的內(nèi)存,并將其劃分為PoolSize個(gè)大小為sizeof(T)的內(nèi)存塊。這些內(nèi)存塊的地址被添加到freeChunks_列表中,表示它們是空閑的,可以被分配。F4528資訊網(wǎng)——每日最新資訊28at.com

AdvancedMemoryPool() {    expandPool();}private:void expandPool() {    char* newBlock = new char[sizeof(T) * PoolSize];    for (size_t i = 0; i < PoolSize; ++i) {        freeChunks_.push_back(reinterpret_cast<T*>(newBlock + i * sizeof(T)));    }    pool_.push_back(newBlock);}

3. 分配內(nèi)存塊

alloc函數(shù)用于從內(nèi)存池中分配一個(gè)空閑的內(nèi)存塊。它首先檢查freeChunks_列表是否為空。如果為空,則調(diào)用expandPool函數(shù)來擴(kuò)展內(nèi)存池。然后,它從freeChunks_列表中取出一個(gè)空閑的內(nèi)存塊,并將其從列表中移除。最后,返回這個(gè)內(nèi)存塊的地址。F4528資訊網(wǎng)——每日最新資訊28at.com

T* alloc() {    std::lock_guard<std::mutex> lock(mutex_); // 確保線程安全    if (freeChunks_.empty()) {        expandPool();    }    T* ptr = freeChunks_.front();    freeChunks_.pop_front();    return ptr;}

這里使用了std::lock_guard來確保在多線程環(huán)境下的線程安全。當(dāng)多個(gè)線程同時(shí)嘗試分配內(nèi)存時(shí),std::mutex會(huì)確保同一時(shí)間只有一個(gè)線程能夠訪問內(nèi)存池。F4528資訊網(wǎng)——每日最新資訊28at.com

4. 回收內(nèi)存塊

dealloc函數(shù)用于回收一個(gè)之前分配的內(nèi)存塊。它接受一個(gè)指向要回收的內(nèi)存塊的指針,并將這個(gè)指針添加到freeChunks_列表中,表示這個(gè)內(nèi)存塊現(xiàn)在是空閑的,可以被再次分配。F4528資訊網(wǎng)——每日最新資訊28at.com

void dealloc(T* ptr) {    assert(ptr != nullptr); // 確保傳入的指針不為空    std::lock_guard<std::mutex> lock(mutex_); // 確保線程安全    freeChunks_.push_back(ptr);}

同樣,這里也使用了std::lock_guard來確保線程安全。F4528資訊網(wǎng)——每日最新資訊28at.com

5. 查詢內(nèi)存池狀態(tài)

我們還提供了兩個(gè)函數(shù)getFreeChunksCount和getUsedChunksCount來查詢內(nèi)存池的狀態(tài)。這兩個(gè)函數(shù)分別返回空閑和已使用的內(nèi)存塊數(shù)量。F4528資訊網(wǎng)——每日最新資訊28at.com

size_t getFreeChunksCount() const {    std::lock_guard<std::mutex> lock(mutex_); // 確保線程安全    return freeChunks_.size();}size_t getUsedChunksCount() const {    return PoolSize - getFreeChunksCount();}

三、使用內(nèi)存池

在主函數(shù)中,我們創(chuàng)建了一個(gè)AdvancedMemoryPool對象,并使用它來分配和回收內(nèi)存塊。通過調(diào)用alloc函數(shù),我們可以從內(nèi)存池中獲取一個(gè)空閑的內(nèi)存塊,并使用它來存儲(chǔ)數(shù)據(jù)。當(dāng)我們不再需要這個(gè)內(nèi)存塊時(shí),可以調(diào)用dealloc函數(shù)將其回收回內(nèi)存池。F4528資訊網(wǎng)——每日最新資訊28at.com

四、完整代碼

#include <iostream>  #include <list>  #include <mutex>  #include <cassert>  #include <cstdlib>    template <typename T, size_t PoolSize = 100>  class AdvancedMemoryPool {  public:      AdvancedMemoryPool() {          expandPool();      }        ~AdvancedMemoryPool() {          std::lock_guard<std::mutex> lock(mutex_);          for (auto& chunk : pool_) {              delete[] reinterpret_cast<char*>(chunk);          }      }        T* alloc() {          std::lock_guard<std::mutex> lock(mutex_);          if (freeChunks_.empty()) {              expandPool();          }            T* ptr = freeChunks_.front();          freeChunks_.pop_front();          return ptr;      }        void dealloc(T* ptr) {          assert(ptr != nullptr);          std::lock_guard<std::mutex> lock(mutex_);          freeChunks_.push_back(ptr);      }        size_t getFreeChunksCount() const {          std::lock_guard<std::mutex> lock(mutex_);          return freeChunks_.size();      }        size_t getUsedChunksCount() const {          return PoolSize - getFreeChunksCount();      }    private:      void expandPool() {          char* newBlock = new char[sizeof(T) * PoolSize];          for (size_t i = 0; i < PoolSize; ++i) {              freeChunks_.push_back(reinterpret_cast<T*>(newBlock + i * sizeof(T)));          }          pool_.push_back(newBlock);      }        mutable std::mutex mutex_;      std::list<T*> freeChunks_;      std::list<char*> pool_;  };    // 使用示例  struct ComplexObject {      int data[100];      // 假設(shè)這是一個(gè)復(fù)雜的對象,需要?jiǎng)討B(tài)分配  };    int main() {      AdvancedMemoryPool<ComplexObject> pool;        ComplexObject* obj1 = pool.alloc();      ComplexObject* obj2 = pool.alloc();        std::cout << "Free chunks: " << pool.getFreeChunksCount() << std::endl;      std::cout << "Used chunks: " << pool.getUsedChunksCount() << std::endl;        pool.dealloc(obj1);      pool.dealloc(obj2);        std::cout << "Free chunks after deallocation: " << pool.getFreeChunksCount() << std::endl;      std::cout << "Used chunks after deallocation: " << pool.getUsedChunksCount() << std::endl;        return 0;  }

本文鏈接:http://www.www897cc.com/showinfo-26-86997-0.html如何用C++實(shí)現(xiàn)簡單的內(nèi)存池

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 微服務(wù)架構(gòu)中的挑戰(zhàn)及應(yīng)對方式:Outbox 模式

下一篇: React 合成事件和 JavaScript 事件有什么區(qū)別?

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 任丘市| 庆元县| 永城市| 土默特右旗| 封丘县| 仙居县| 西乌珠穆沁旗| 西吉县| 平江县| 额尔古纳市| 鸡泽县| 微山县| 普宁市| 都匀市| 大同市| 济阳县| 永丰县| 南川市| 万山特区| 喜德县| 曲麻莱县| 清徐县| 收藏| 佛学| 汽车| 麟游县| 安多县| 湄潭县| 十堰市| 建阳市| 全椒县| 武清区| 琼结县| 太仆寺旗| 商洛市| 太原市| 花垣县| 镇赉县| 邛崃市| 赫章县| 海淀区|