網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
C++內(nèi)存管理之簡(jiǎn)易內(nèi)存池的實(shí)現(xiàn)_C 語(yǔ)言
作者:Kayden_Cheung ? 更新時(shí)間: 2021-12-30 編程語(yǔ)言什么是內(nèi)存池?
頻繁的調(diào)用 malloc 會(huì)影響運(yùn)行效率以及產(chǎn)生額外的 cookie, 而內(nèi)存池的思想是預(yù)先申請(qǐng)一大塊內(nèi)存,當(dāng)有內(nèi)存申請(qǐng)需求時(shí),從內(nèi)存池中取出一塊內(nèi)存分配給目標(biāo)對(duì)象。
它的實(shí)現(xiàn)過(guò)程為:
預(yù)先申請(qǐng) chunk 大小的內(nèi)存池, 將內(nèi)存池劃按照對(duì)象大小劃分成多個(gè)內(nèi)存塊。以鏈表的形式,即通過(guò)指針將內(nèi)存塊相連,頭指針指向第一個(gè)空閑塊。當(dāng)有內(nèi)存申請(qǐng)需求時(shí),首先檢查頭指針是否指向空閑塊,如果是則將頭指針指向的第一個(gè)空閑塊分配出去(從鏈表移除),同時(shí)頭指針指向下一個(gè)空閑塊;若頭指針為空,說(shuō)明當(dāng)前內(nèi)存池已分配完,需要重新申請(qǐng)新的內(nèi)存池。當(dāng)有內(nèi)存釋放需求時(shí),將釋放的內(nèi)存塊重新加入鏈表的表頭,調(diào)整頭指針指向新加入的空閑塊。這也意味著,如果申請(qǐng)了多個(gè)內(nèi)存池,在內(nèi)存釋放的過(guò)程中會(huì)慢慢的合并到一起。
初步實(shí)現(xiàn)
在上面的代碼中設(shè)置一個(gè)內(nèi)存池為5個(gè)內(nèi)存塊,當(dāng)我們進(jìn)行100次內(nèi)存申請(qǐng)后,打印出前10個(gè)地址查看,可以看到前5個(gè)地址是連續(xù)的,后5個(gè)也是連續(xù)的,但中間由于重新申請(qǐng)了內(nèi)存池,所以不是連續(xù)的。
但是這樣的方法還存在著問(wèn)題,那就是引入了額外的指針內(nèi)存消耗,接下來(lái)將使用embedded pointer進(jìn)行改進(jìn)。
使用嵌入指針改進(jìn)
上面就使用到了嵌入指針,一個(gè) AirplaneRep 對(duì)象的大小為 8 字節(jié),而一個(gè) Airplane 的指針大小為 4 字節(jié)或 8 字節(jié)。在 32 位機(jī)器下, 指針可以借用 AirplaneRep 對(duì)象所占的 8 字節(jié)內(nèi)存空間中的前 4 個(gè)字節(jié),用來(lái)連接空閑的內(nèi)存塊。而當(dāng)內(nèi)存塊需要被分配給對(duì)象時(shí),此時(shí)它已從鏈表中移除,也就不需要指針來(lái)連接了。此時(shí)的 8 字節(jié)內(nèi)存空間由 AirplaneRep 占據(jù)。當(dāng)內(nèi)存釋放時(shí)也是同理,由于 Rep 和 next 不會(huì)同時(shí)用到,所以 embedded pointer 的做法可以減少內(nèi)存消耗。
更簡(jiǎn)化:static allocator
前面的實(shí)現(xiàn)需要為每個(gè)類都重寫 operator new 和 operator delete,由于內(nèi)容是一樣的,使用另一個(gè)類來(lái)完成這些重復(fù)的操作。
如此一來(lái),我們的 class 只需要去調(diào)用 allocator 即可完成內(nèi)存的申請(qǐng)和釋放工作。
macor for static allocator
在上面的 Foo 和 Goo 中,每次還要寫一大堆重復(fù)的內(nèi)容,于是可以使用宏進(jìn)一步簡(jiǎn)化:
原文鏈接:https://www.cnblogs.com/zyb993963526/p/15684908.html
相關(guān)推薦
- 2022-09-06 Python進(jìn)程管理神器Supervisor詳解_python
- 2022-11-23 Pandas?DataFrame操作數(shù)據(jù)增刪查改_python
- 2023-07-10 匿名內(nèi)部類、Lambda表達(dá)式、方法引用對(duì)比分析
- 2022-03-30 解決Microsoft?Visual?C++?2010?Express?運(yùn)行及調(diào)試問(wèn)題_C 語(yǔ)言
- 2022-06-22 Python?Tkinter?GUI編程實(shí)現(xiàn)Frame切換_python
- 2022-08-10 Qt利用DOM類實(shí)現(xiàn)讀取xml文件_C 語(yǔ)言
- 2023-07-03 Python實(shí)現(xiàn)曲線的肘部點(diǎn)檢測(cè)詳解_python
- 2022-06-09 Nginx速查手冊(cè)及常見(jiàn)問(wèn)題_nginx
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支