詳解利用C語(yǔ)言如何實(shí)現(xiàn)簡(jiǎn)單的內(nèi)存池
前言
在編程過(guò)程中,尤其是對(duì)于C語(yǔ)言開(kāi)發(fā)者,其實(shí)編程就是在使用內(nèi)存,不停地變化內(nèi)存中的數(shù)據(jù)。當(dāng)我們想開(kāi)辟一片新的內(nèi)存使用時(shí),就會(huì)使用malloc實(shí)現(xiàn)。但是通過(guò)查閱很多資料,發(fā)現(xiàn)頻繁的使用malloc并不是很好的選擇。原因就是如果頻繁的申請(qǐng)、釋放內(nèi)存,操作系統(tǒng)由于內(nèi)存管理算法原因,導(dǎo)致出現(xiàn)內(nèi)存碎片。其實(shí)產(chǎn)生碎片是一件很平常的事情,為何會(huì)這樣,我想主要是內(nèi)存利用率與性能的一個(gè)平衡。如果操作系統(tǒng)很摳門(mén),肯定會(huì)把內(nèi)存分配的邏輯算的很?chē)?yán)密,“見(jiàn)縫插針”這四個(gè)字能很到的詮釋內(nèi)存分配策略。正因?yàn)橐?jiàn)縫插針,經(jīng)過(guò)很長(zhǎng)的使用,內(nèi)存上會(huì)遍布“針眼”,但是由于針眼普遍很小,當(dāng)你再去插一個(gè)較粗的針的時(shí)候,往往很久“插不進(jìn)去”。因?yàn)樾枰袛噙@么多針眼哪個(gè)足夠?qū)捤傻哪懿暹M(jìn)去這根針。
所以,如果我們不那么摳的去實(shí)現(xiàn)內(nèi)存分配,是不是在性能上會(huì)有很大的提高呢?答案絕對(duì)是肯定的,而且隨著硬件技術(shù)的提升,內(nèi)存已經(jīng)不是當(dāng)年的容量,服務(wù)器起步也得是16G吧,32 64也是很常見(jiàn)的。就連現(xiàn)在手機(jī)都有6G內(nèi)存的,實(shí)在令臺(tái)式機(jī)服務(wù)器都汗顏。
在內(nèi)存池的實(shí)現(xiàn)結(jié)尾,會(huì)加入一塊內(nèi)存池使用率監(jiān)測(cè)打印,開(kāi)發(fā)一種內(nèi)存池,通吃所有的項(xiàng)目場(chǎng)景,顯然是不可取的。說(shuō)一個(gè)比較時(shí)尚的名詞“機(jī)器學(xué)習(xí)”。這塊的目的在于通過(guò)觀測(cè)內(nèi)存池的使用率,從而發(fā)現(xiàn)哪些長(zhǎng)度的內(nèi)存比較受項(xiàng)目的歡迎,需要多設(shè),哪些長(zhǎng)度的內(nèi)存使用較少,需要少設(shè)。哪些長(zhǎng)度的沒(méi)有,需要新設(shè)等等。目前這塊是純手動(dòng)的,并不是動(dòng)態(tài)變化的,有些調(diào)優(yōu)的感覺(jué)。
內(nèi)存時(shí)原理說(shuō)明
模擬C語(yǔ)言內(nèi)存分配函數(shù)malloc()和free(),我們這里也定義兩個(gè)函數(shù)alloc和afree,進(jìn)而模擬C語(yǔ)言內(nèi)存的分配的實(shí)現(xiàn)。
- 定義一個(gè)大的字符數(shù)組,模擬一塊內(nèi)存池。
- 讓alloc對(duì)一個(gè)大的字符數(shù)組allocbuf中的空間進(jìn)行分配,該數(shù)組是alloc和afree兩個(gè)函數(shù)私有的數(shù)組。
- 由于alloc和afree處理的對(duì)象是指針而不是數(shù)組下標(biāo),因此,其他函數(shù)無(wú)需知道該數(shù)組的名字,這樣可以在alloc和afree處理的對(duì)象是指針而不是數(shù)組下標(biāo),因此,其他函數(shù)無(wú)需知道該數(shù)組的名字。
- 他可以在調(diào)用malloc函數(shù)或量操作系統(tǒng)申請(qǐng)一個(gè)指向操作系統(tǒng)申請(qǐng)一個(gè)指向無(wú)名存儲(chǔ)塊的指針獲得。
- allocbuf中的空間使用情況也是我們需要了解,因此用allocp指針指向allocbuf數(shù)組中下一個(gè)空閑單元。當(dāng)調(diào)用alloc申請(qǐng)n個(gè)字符時(shí)空間時(shí),alloc檢查allocbuf中的下一個(gè)空閑單元。當(dāng)調(diào)用alloc申請(qǐng)n個(gè)字符的空間時(shí),alloc檢查allocbuf中有沒(méi)由足夠的空閑空間。如果有足夠的空閑空間,則返回空閑塊的當(dāng)前位置,如果空間不夠則返回0.
下面是簡(jiǎn)易內(nèi)存池的實(shí)現(xiàn)原理圖:
其實(shí)這個(gè)模型可以幫助我們理解關(guān)于malloc和free函數(shù)的很多東西。
代碼實(shí)現(xiàn)
#define ALLOCSIZE 10000 /* 可用空間的大小*/ static char allocbuf[ALLOCSIZE]; /* alloc使用的存儲(chǔ)區(qū) */ static char *allocp = allocbuf; /* 下一個(gè)空閑位置 */ char *alloc(int n) { if(allocbuf + ALLOCSIZE - allocp > n) { /* 有足夠的空間 */ allocp += n; return allocp - n; /* 分配前的指針P */ } else { /* 空間不夠 */ return 0; } } void afree(char *p) /* 釋放p指向的存儲(chǔ)區(qū) */ { if(p >= allocbuf && p < allocbuf + ALLOCSIZE ) allocp = p; }
總結(jié)
到此這篇關(guān)于C語(yǔ)言如何實(shí)現(xiàn)簡(jiǎn)單的內(nèi)存池的文章就介紹到這了,更多相關(guān)C語(yǔ)言實(shí)現(xiàn)內(nèi)存池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用VC6.0對(duì)C語(yǔ)言程序進(jìn)行調(diào)試的基本手段分享
這篇文章主要介紹了用VC6.0開(kāi)發(fā)c語(yǔ)言程序的時(shí)候調(diào)試代碼的一些小技巧,需要的朋友可以參考下2013-07-07QT中進(jìn)程的創(chuàng)建實(shí)現(xiàn)
本文主要介紹了QT中進(jìn)程的創(chuàng)建實(shí)現(xiàn),詳細(xì)介紹了創(chuàng)建進(jìn)程的整個(gè)過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2023-08-08C++編程之CString、string與、char數(shù)組的轉(zhuǎn)換
這篇文章主要介紹了C++編程之CString、string與、char數(shù)組的轉(zhuǎn)換的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下2017-10-10一篇文章教你自己動(dòng)手實(shí)現(xiàn)C語(yǔ)言庫(kù)函數(shù)
這篇文章主要介紹了C語(yǔ)言庫(kù)函數(shù)的相關(guān)資料,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-09-09C語(yǔ)言程序設(shè)計(jì)譚浩強(qiáng)第五版課后答案(第三章習(xí)題答案)
這篇文章主要介紹了C語(yǔ)言程序設(shè)計(jì)譚浩強(qiáng)第五版課后答案(第三章習(xí)題答案),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-04-04關(guān)于C++虛繼承的內(nèi)存模型問(wèn)題
C++虛繼承的內(nèi)存模型是一個(gè)老生常談的話題,實(shí)現(xiàn)方法主要依賴于編譯器,本文從多個(gè)角度通過(guò)代碼詳解C++中虛繼承的內(nèi)存模型知識(shí),感興趣的朋友跟隨小編一起看看吧2021-07-07c++中struct和class的區(qū)別小結(jié)
在C++中,class和struct都是用于定義自定義數(shù)據(jù)類(lèi)型的關(guān)鍵字,本文主要介紹了c++中struct和class的區(qū)別小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下2023-08-08