1.Redis學習--本地Redis實現之內存池

最近在學習redis源碼,想着光看不如自己動動手,於是寫了個localRedis

如名字所示,這是個本地數據庫,有着與redis類似的命令接口,但內部實現比較簡單,只提取了一些主要邏輯

如有錯誤或不合理的地方,懇請指出!謝謝!

源碼地址:    https://github.com/BAN1993/localRedis


(這篇文章主要是內存池的實現,與redis關係不大~)

 

目的

做這個內存池主要目的是爲了方便管理內存和減少內存碎片,但是效率會比new/delete低(這裏只是簡單測試結果)。

另外還有一個後面調試才發現的好處(適合學習,不適合用在項目中),可以在程序退出時打印忘記釋放的內存。比如:

#include "base.h"
#include "mallocManager.h"

int main()
{
	char* c = (char*)__new(1024);
	sprintf(c,"hello word!");
	LOG(c);
	
	return 0;
}

最後編譯運行會輸出如下:

[main:8]hello word!
[~mallocManager:10]UNDELETE:filename=main.cpp,line=6

 

設計

這個內存池的核心思想是每次申請大塊內存,然後拆分成N塊小內存插入到空閒隊列供後面取用。new時從空閒隊列取,隊列爲空就繼續申請大塊內存;delete時將內存插回空閒隊列。

 

流程

我們會將取用的內存大小向上調整爲整數(2的倍數,8,16,32......2K,4K,8K),每種大小都會維護一個內存池。

比如想要取用一塊char[5]的內存時,我們會返回一塊8字節的內存:

    ①若相應池中空閒隊列不爲空,直接返回

    ②若相應池中空閒隊列爲空,先申請一塊8K大小的內存,將它拆分成8192/8塊,逐一插入空閒隊列再返回其一

 

經過一段時間的取用後,內存使用情況可能如下:

可以看到目前只創建並使用了8,128,4K三種類型的內存池,其中8空閒還比較多;128已滿,下次取用就會擴充;4K還有一塊空閒。

若一次申請的內存大於8K,那麼會直接申請相應大小的內存塊並存到一個big列表中,釋放時也是直接刪除。

 

例子

#include "base.h"
#include "mallocManager.h"

class TestA
{
public:
	TestA(int size)
	{
		size = size <= 0 ? 1 : size;
		// m_p = new char[size];
		// or
		m_p = (char*)__new(size);
	}
	
	~TestA()
	{
		if(m_p)
		{
			// delete[] m_p;
			// or
			__delete(m_p);
		}
		m_p = nullptr;
	}
	
private:
	char* m_p;
};

int main()
{
	__new_obj_1(TestA, p, 666);
	
	// do something
	// p->...
	
	__delete_obj(TestA, p);
	
	return 0;
}

實現源碼見:https://github.com/BAN1993/localRedis

mallocPool.cpp/.h

mallocManager.cpp/.h

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章