当前位置: 首页 > news >正文

C++中内存池的简单原理及实现详解

为什么要用内存池

C++程序默认的内存管理(new,delete,malloc,free)会频繁地在堆上分配和释放内存,导致性能的损失,产生大量的内存碎片,降低内存的利用率。默认的内存管理因为被设计的比较通用,所以在性能上并不能做到极致。

因此,很多时候需要根据业务需求设计专用内存管理器,便于针对特定数据结构和使用场合的内存管理,比如:内存池。

内存池原理

内存池的思想是,在真正使用内存之前,预先申请分配一定数量、大小预设的内存块留作备用。当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存,当内存释放后就回归到内存块留作后续的复用,使得内存使用效率得到提升,一般也不会产生不可控制的内存碎片。

内存池设计

算法原理:

1.预申请一个内存区chunk,将内存中按照对象大小划分成多个内存块block

2.维持一个空闲内存块链表,通过指针相连,标记头指针为第一个空闲块

3.每次新申请一个对象的空间,则将该内存块从空闲链表中去除,更新空闲链表头指针

4.每次释放一个对象的空间,则重新将该内存块加到空闲链表头

5.如果一个内存区占满了,则新开辟一个内存区,维持一个内存区的链表,同指针相连,头指针指向最新的内存区,新的内存块从该区内重新划分和申请

如图所示:

内存池实现

memory_pool.hpp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

#ifndef _MEMORY_POOL_H_

#define _MEMORY_POOL_H_

#include <stdint.h>

#include <mutex>

template<size_tBlockSize,size_tBlockNum = 10>

classMemoryPool

{

public:

MemoryPool()

{

std::lock_guard<std::mutex> lk(mtx);// avoid race condition

// init empty memory pointer

free_block_head = NULL;

mem_chunk_head = NULL;

}

~MemoryPool()

{

std::lock_guard<std::mutex> lk(mtx);// avoid race condition

// destruct automatically

MemChunk* p;

while(mem_chunk_head)

{

p = mem_chunk_head->next;

deletemem_chunk_head;

mem_chunk_head = p;

}

}

void* allocate()

{

std::lock_guard<std::mutex> lk(mtx);// avoid race condition

// allocate one object memory

// if no free block in current chunk, should create new chunk

if(!free_block_head)

{

// malloc mem chunk

MemChunk* new_chunk =newMemChunk;

new_chunk->next = NULL;

// set this chunk's first block as free block head

free_block_head = &(new_chunk->blocks[0]);

// link the new chunk's all blocks

for(inti = 1; i < BlockNum; i++)

new_chunk->blocks[i - 1].next = &(new_chunk->blocks[i]);

new_chunk->blocks[BlockNum - 1].next = NULL;// final block next is NULL

if(!mem_chunk_head)

mem_chunk_head = new_chunk;

else

{

// add new chunk to chunk list

mem_chunk_head->next = new_chunk;

mem_chunk_head = new_chunk;

}

}

// allocate the current free block to the object

void* object_block = free_block_head;

free_block_head = free_block_head->next;

returnobject_block;

}

void* allocate(size_tsize)

{

std::lock_guard<std::mutex> lk(array_mtx);// avoid race condition for continuous memory

// calculate objects num

intn = size / BlockSize;

// allocate n objects in continuous memory

// FIXME: make sure n > 0

void* p = allocate();

for(inti = 1; i < n; i++)

allocate();

returnp;

}

voiddeallocate(void* p)

{

std::lock_guard<std::mutex> lk(mtx);// avoid race condition

// free object memory

FreeBlock* block =static_cast<FreeBlock*>(p);

block->next = free_block_head;// insert the free block to head

free_block_head = block;

}

private:

// free node block, every block size exactly can contain one object

structFreeBlock

{

unsignedchardata[BlockSize];

FreeBlock* next;

};

FreeBlock* free_block_head;

// memory chunk, every chunk contains blocks number with fixed BlockNum

structMemChunk

{

FreeBlock blocks[BlockNum];

MemChunk* next;

};

MemChunk* mem_chunk_head;

// thread safe related

std::mutex mtx;

std::mutex array_mtx;

};

#endif // !_MEMORY_POOL_H_

main.cpp

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

#include <iostream>

#include "memory_pool.hpp"

classMyObject

{

public:

MyObject(intx): data(x)

{

//std::cout << "contruct object" << std::endl;

}

~MyObject()

{

//std::cout << "destruct object" << std::endl;

}

intdata;

// override new and delete to use memory pool

void* operatornew(size_tsize);

voidoperatordelete(void* p);

void* operatornew[](size_tsize);

voidoperatordelete[](void* p);

};

// define memory pool with block size as class size

MemoryPool<sizeof(MyObject), 3> gMemPool;

void* MyObject::operatornew(size_tsize)

{

//std::cout << "new object space" << std::endl;

returngMemPool.allocate();

}

voidMyObject::operatordelete(void* p)

{

//std::cout << "free object space" << std::endl;

gMemPool.deallocate(p);

}

void* MyObject::operatornew[](size_tsize)

{

// TODO: not supported continuous memoery pool for now

//return gMemPool.allocate(size);

returnNULL;

}

voidMyObject::operatordelete[](void* p)

{

// TODO: not supported continuous memoery pool for now

//gMemPool.deallocate(p);

}

intmain(intargc,char* argv[])

{

MyObject* p1 =newMyObject(1);

std::cout <<"p1 "<< p1 <<" "<< p1->data<< std::endl;

MyObject* p2 =newMyObject(2);

std::cout <<"p2 "<< p2 <<" "<< p2->data << std::endl;

deletep2;

MyObject* p3 =newMyObject(3);

std::cout <<"p3 "<< p3 <<" "<< p3->data << std::endl;

MyObject* p4 =newMyObject(4);

std::cout <<"p4 "<< p4 <<" "<< p4->data << std::endl;

MyObject* p5 =newMyObject(5);

std::cout <<"p5 "<< p5 <<" "<< p5->data << std::endl;

MyObject* p6 =newMyObject(6);

std::cout <<"p6 "<< p6 <<" "<< p6->data << std::endl;

deletep1;

deletep2;

//delete p3;

deletep4;

deletep5;

deletep6;

getchar();

return0;

}

运行结果

p1 00000174BEDE0440 1
p2 00000174BEDE0450 2
p3 00000174BEDE0450 3
p4 00000174BEDE0460 4
p5 00000174BEDD5310 5
p6 00000174BEDD5320 6

可以看到内存地址是连续,并且回收一个节点后,依然有序地开辟内存
对象先开辟内存再构造,先析构再释放内存

注意

  • 在内存分配和释放的环节需要加锁来保证线程安全
  • 还没有实现对象数组的分配和释放

https://gitee.com/sdger1/gfd/blob/master/IUbeb.md
https://gitee.com/sdger1/gfd/blob/master/gFQji.md
https://gitee.com/sdger1/gfd/blob/master/NGqDL.md
https://gitee.com/sdger1/gfd/blob/master/VmTsR.md
https://gitee.com/sdger1/gfd/blob/master/iODwe.md
https://gitee.com/sdger1/gfd/blob/master/OaxTf.md
https://gitee.com/sdger1/gfd/blob/master/xHOGb.md
https://gitee.com/sdger1/gfd/blob/master/sltat.md
https://gitee.com/sdger1/gfd/blob/master/ssipT.md
https://gitee.com/sdger1/gfd/blob/master/ZUuiD.md
https://gitee.com/sdger1/gfd/blob/master/zJUvh.md
https://gitee.com/sdger1/gfd/blob/master/PNTWl.md
https://gitee.com/sdger1/gfd/blob/master/PsIep.md
https://gitee.com/sdger1/gfd/blob/master/mHSIE.md
https://gitee.com/sdger1/gfd/blob/master/cVqSE.md
https://gitee.com/sdger1/gfd/blob/master/meOOp.md
https://gitee.com/sdger1/gfd/blob/master/otVqz.md
https://gitee.com/sdger1/gfd/blob/master/jRvhC.md
https://gitee.com/sdger1/gfd/blob/master/SYHiR.md
https://gitee.com/sdger1/gfd/blob/master/CPXGd.md
https://gitee.com/sdger1/gfd/blob/master/xqItR.md
https://gitee.com/sdger1/gfd/blob/master/sbGBK.md
https://gitee.com/sdger1/gfd/blob/master/oVDbK.md
https://gitee.com/sdger1/gfd/blob/master/hcTzi.md
https://gitee.com/sdger1/gfd/blob/master/jUICZ.md
https://gitee.com/sdger1/gfd/blob/master/itnJK.md
https://gitee.com/sdger1/gfd/blob/master/bXswt.md
https://gitee.com/sdger1/gfd/blob/master/bjYJd.md
https://gitee.com/sdger1/gfd/blob/master/KXqmy.md
https://gitee.com/sdger1/gfd/blob/master/laLWX.md
https://gitee.com/sdger1/gfd/blob/master/Auddm.md
https://gitee.com/sdger1/gfd/blob/master/nIwVc.md
https://gitee.com/sdger1/gfd/blob/master/NAaOE.md
https://gitee.com/sdger1/gfd/blob/master/ZwWFg.md
https://gitee.com/sdger1/gfd/blob/master/VcSOW.md
https://gitee.com/sdger1/gfd/blob/master/QuUmw.md
https://gitee.com/sdger1/gfd/blob/master/xdBXL.md
https://gitee.com/sdger1/gfd/blob/master/APGaU.md
https://gitee.com/sdger1/gfd/blob/master/hfeOb.md
https://gitee.com/sdger1/gfd/blob/master/GqQZJ.md
https://gitee.com/sdger1/gfd/blob/master/tPZOM.md
https://gitee.com/sdger1/gfd/blob/master/LyyhN.md
https://gitee.com/sdger1/gfd/blob/master/rbLLV.md
https://gitee.com/sdger1/gfd/blob/master/ySagR.md
https://gitee.com/sdger1/gfd/blob/master/iOaQl.md
https://gitee.com/sdger1/gfd/blob/master/ntgWQ.md
https://gitee.com/sdger1/gfd/blob/master/BDPyQ.md
https://gitee.com/sdger1/gfd/blob/master/STISE.md
https://gitee.com/sdger1/gfd/blob/master/keNlX.md
https://gitee.com/sdger1/gfd/blob/master/pZhlh.md
https://gitee.com/sdger1/gfd/blob/master/NfStS.md
https://gitee.com/sdger1/gfd/blob/master/xsLJG.md
https://gitee.com/sdger1/gfd/blob/master/GmvQi.md
https://gitee.com/sdger1/gfd/blob/master/OhZkn.md
https://gitee.com/sdger1/gfd/blob/master/lUnPw.md
https://gitee.com/sdger1/gfd/blob/master/JCtsK.md
https://gitee.com/sdger1/gfd/blob/master/zWJqZ.md
https://gitee.com/sdger1/gfd/blob/master/dybxu.md
https://gitee.com/sdger1/gfd/blob/master/ircGP.md
https://gitee.com/sdger1/gfd/blob/master/SLtgb.md
https://gitee.com/sdger1/gfd/blob/master/kfVFz.md
https://gitee.com/sdger1/gfd/blob/master/jsHfF.md
https://gitee.com/sdger1/gfd/blob/master/hscdn.md
https://gitee.com/sdger1/gfd/blob/master/vKfEU.md
https://gitee.com/sdger1/gfd/blob/master/nkFDa.md
https://gitee.com/sdger1/gfd/blob/master/QhKht.md
https://gitee.com/sdger1/gfd/blob/master/SdDPc.md
https://gitee.com/sdger1/gfd/blob/master/GJIEH.md
https://gitee.com/sdger1/gfd/blob/master/NsLGU.md
https://gitee.com/sdger1/gfd/blob/master/EUdkX.md
https://gitee.com/sdger1/gfd/blob/master/DOlhD.md
https://gitee.com/sdger1/gfd/blob/master/FscsK.md
https://gitee.com/sdger1/gfd/blob/master/AIpBc.md
https://gitee.com/sdger1/gfd/blob/master/hpYLZ.md
https://gitee.com/sdger1/gfd/blob/master/dJcDk.md
https://gitee.com/sdger1/gfd/blob/master/AramM.md
https://gitee.com/sdger1/gfd/blob/master/DQDyw.md
https://gitee.com/sdger1/gfd/blob/master/kicEg.md
https://gitee.com/sdger1/gfd/blob/master/NWFGp.md
https://gitee.com/sdger1/gfd/blob/master/pyPQq.md
https://gitee.com/sdger1/gfd/blob/master/miVts.md
https://gitee.com/sdger1/gfd/blob/master/BDWNq.md
https://gitee.com/sdger1/gfd/blob/master/cywIV.md
https://gitee.com/sdger1/gfd/blob/master/fYcDo.md
https://gitee.com/sdger1/gfd/blob/master/NUmLu.md
https://gitee.com/sdger1/gfd/blob/master/KAvgp.md
https://gitee.com/sdger1/gfd/blob/master/ijXsJ.md
https://gitee.com/sdger1/gfd/blob/master/XpMox.md
https://gitee.com/sdger1/gfd/blob/master/abOwN.md
https://gitee.com/sdger1/gfd/blob/master/qydmX.md
https://gitee.com/sdger1/gfd/blob/master/hPOiU.md
https://gitee.com/sdger1/gfd/blob/master/grvVT.md
https://gitee.com/sdger1/gfd/blob/master/owqfj.md
https://gitee.com/sdger1/gfd/blob/master/tawNi.md
https://gitee.com/sdger1/gfd/blob/master/dfmlf.md
https://gitee.com/sdger1/gfd/blob/master/GyeSj.md
https://gitee.com/sdger1/gfd/blob/master/HBbcU.md
https://gitee.com/sdger1/gfd/blob/master/ztFuV.md
https://gitee.com/sdger1/gfd/blob/master/JXGVb.md
https://gitee.com/sdger1/gfd/blob/master/TznMi.md
https://gitee.com/sdger1/gfd/blob/master/AWtsK.md
https://gitee.com/sdger1/gfd/blob/master/jXMvJ.md
https://gitee.com/sdger1/gfd/blob/master/CvUMt.md
https://gitee.com/sdger1/gfd/blob/master/MFoeB.md
https://gitee.com/sdger1/gfd/blob/master/jQXwi.md
https://gitee.com/sdger1/gfd/blob/master/tEmYe.md
https://gitee.com/sdger1/gfd/blob/master/TOcZV.md
https://gitee.com/sdger1/gfd/blob/master/bdFww.md
https://gitee.com/sdger1/gfd/blob/master/lRAVz.md
https://gitee.com/sdger1/gfd/blob/master/PCeiD.md
https://gitee.com/sdger1/gfd/blob/master/nWGbq.md
https://gitee.com/sdger1/gfd/blob/master/VOWYU.md
https://gitee.com/sdger1/gfd/blob/master/jjolD.md
https://gitee.com/sdger1/gfd/blob/master/fmvxV.md
https://gitee.com/sdger1/gfd/blob/master/KEebL.md
https://gitee.com/sdger1/gfd/blob/master/bUUMd.md
https://gitee.com/sdger1/gfd/blob/master/OJUFd.md
https://gitee.com/sdger1/gfd/blob/master/ywaAt.md
https://gitee.com/sdger1/gfd/blob/master/LpepO.md
https://gitee.com/sdger1/gfd/blob/master/zxQSp.md
https://gitee.com/sdger1/gfd/blob/master/MlXGo.md
https://gitee.com/sdger1/gfd/blob/master/FpnAd.md
https://gitee.com/sdger1/gfd/blob/master/keBpq.md
https://gitee.com/sdger1/gfd/blob/master/OyoZb.md
https://gitee.com/sdger1/gfd/blob/master/ooKHv.md
https://gitee.com/sdger1/gfd/blob/master/SqqOG.md
https://gitee.com/sdger1/gfd/blob/master/SFPXh.md
https://gitee.com/sdger1/gfd/blob/master/lVgFB.md
https://gitee.com/sdger1/gfd/blob/master/gJHRS.md
https://gitee.com/sdger1/gfd/blob/master/YLFfy.md
https://gitee.com/sdger1/gfd/blob/master/yIEYN.md
https://gitee.com/sdger1/gfd/blob/master/XYiSn.md

http://www.jsqmd.com/news/1131815/

相关文章:

  • 告别AI能力局限:从零读懂Tool Calling,实现大模型调用外部工具、落地真实业务
  • PCIe 6.0 DMWr 实战:3步配置与 64B/128B 负载性能对比
  • OnlyOffice 编译包跨平台部署:CentOS 7 系统 5 项关键服务配置详解
  • 今天我重读了一次《重构》,说说我觉得能在AI中用到的几个地方
  • 5分钟解锁:FGA如何让你每天从FGO刷本中解放3小时
  • 河南洛阳无人机维修机构推荐|河南筋斗云翼航空一站式低空产业实训基地
  • 首月半价cursor
  • 26-MCP协议是什么
  • Plone安全架构解析:默认拒绝与五维控制的开源实践
  • 深度学习过拟合实战:L1/L2正则化与Dropout在Auto MPG回归任务中的5方案对比
  • VOC、COCO、YOLO 3 种目标检测数据集格式对比与 Python 转换脚本
  • mba法律论文选题
  • NAND Flash 3D/2D 架构演进:从平面到 200+ 层堆叠的容量与性能跃迁
  • UE4 UMG 3D模型显示性能对比:RenderTarget 3种分辨率与2种渲染模式实测
  • (5,2)线性分组码标准阵列译码原理与Python仿真实现【P124302018-王开源,P124302045-张俊豪,P124302003-李则翰,P124302048-张子璇】
  • Linux 用户管理知识与应用实践(三:用户组及修改用户密码)
  • 茶渍 英文分场景 tea stain(通用)
  • 2026最新8款AI编程工具平替实测深度对比
  • R-CNN系列3大模型演进对比:从53.7%到73.2% mAP的性能跃迁分析
  • NinChat使用介绍系列2:web界面实时资讯搜索
  • RTL8723DU 驱动在 RISC-V 平台(全志D1)的蓝牙功能完整测试与排错指南
  • 黎阳之光自研三维重构引擎,赋能全行业全域透明管理
  • UE4 UMG 渲染优化:SceneCapture 2D 3种渲染模式性能对比与选型指南
  • 面试高频:一致性hash算法?
  • HarmonyKit | 鸿蒙新特性规范:10 个工具页 UI 一致性设计系统
  • C++ 捕获鼠标按键(左/右/中键)和滚轮操作的几种路子
  • YAGEKO雅阁固企业文化理念与未来发展布局
  • 从零开始成为白帽黑客:Web安全漏洞挖掘实战入门指南
  • 企业人才战略规划
  • Grok Build:从构建工具到工作流语义引擎的范式跃迁