模擬實現空間配置器

2021-08-28 02:18:36 字數 4368 閱讀 4609

實現背景:malloc在申請空間的時候會有很多缺陷,比如:效率比較低下,容易造成記憶體碎片,也容易造成空間額外的浪費,如果使用者自己釋放空間操作不當,還會產生記憶體洩漏的問題

實現方法:若使用者申請的空間大於128位元組,定為大塊記憶體,採用一級空間配置器的處理方法

若使用者申請的空間小於等於128位元組,定為小塊記憶體,採用二級空間配置器的處理方法

具體實現原理

一級空間配置器:對malloc和new的封裝+空間不足的應對措施

二級空間配置器:採用記憶體池技術+小塊記憶體空間的管理效率

結果顯示:

// 用於除錯追蹤的trace log

inline static void _trace_debug(const char * funcname,

const char * filename, int line, char* format, ...)

#define __trace_debug(...) \

_trace_debug(__funcdname__, __file__, __line__, __va_args__);

typedef void(*poom)();

// 一級空間配置器: 大於128位元組的空間

// 原理:malloc + free 封裝 考慮記憶體空間不足

templateclass mallocalloctemplate

return res;

} static void deallocate(void* p, size_t/* size*/)

// oom: out of memory

static void* oom_malloc(size_t size)

}} static poom sethandle(poom poom)

private:

static poom _poomfunc;

};templatepoom mallocalloctemplate::_poomfunc = null;

typedef mallocalloctemplate<0> mallocalloc;

templateclass defaultallocatetemplate

; enum ;

enum ;

union obj

;public:

static void* allocate(size_t size)

printf("\n");

// 小塊記憶體

__trace_debug("size 小於128,二級空間配置器\n");

obj* res;

size_t index = freelist_index(size);

if (null == _freelist[index])

printf("\n");

__trace_debug("二級空間配置器:_freelist[%d]: %d\n", index, size);

res = _freelist[index];

_freelist[index] = res->free_list_link;

return res;

} static void deallocate(void* p, size_t size)

printf("\n");

size_t index = freelist_index(size);

((obj*)p)->free_list_link = _freelist[index];

_freelist[index] = (obj*)p;

__trace_debug("二級空間配置器: _freelist[%d]\n", index);

}private:

// 想辦法去找nobjs個size位元組的記憶體塊出來

static void* chunkalloc(int& nobjs, size_t size)

else if (leftbytes >= size)

else

size_t getbytes = totalbytes * 2 + round_up(_heapsize >> 4);

// 1. 超系統要空間

_startfree = (char*)malloc(getbytes);

__trace_debug("二級空間配置器:像系統索要記憶體空間%d\n", getbytes);

if (null == _startfree)

}// 也沒有更大的記憶體塊

__trace_debug("二級空間配置器:在雜湊桶中沒有找到,向一級空間配置器索要\n");

_endfree = 0;

_startfree = (char*)mallocalloc::allocate(size);

}_endfree = _startfree + getbytes;

_heapsize += getbytes;

return chunkalloc(nobjs, size);

} }static void* refill(size_t size)

__trace_debug("二級空間配置器:從記憶體池中要到%個記憶體塊\n", nobjs);

void* res = p;

p += size;

// 將剩餘的nobjs-1塊的小塊記憶體掛到對應的鍊錶中

size_t index = freelist_index(size);

obj* cur = null;

int i = 1;

while (i < nobjs)

return res;

} static size_t round_up(size_t bytes)

static size_t freelist_index(size_t bytes)

private:

static obj* _freelist[__nfreelists];

static char* _startfree; // 記憶體池的起始位置

static char* _endfree; // 記憶體池的結束位置

static size_t _heapsize; // 總共向系統堆索要空間的總大小

};templatechar* defaultallocatetemplate::_startfree = 0;

templatechar* defaultallocatetemplate::_endfree = 0;

templatesize_t defaultallocatetemplate::_heapsize = 0;

templatetypename defaultallocatetemplate::obj* defaultallocatetemplate::_freelist[__nfreelists] = ;

typedef defaultallocatetemplate<0> defalloc;

#ifdef use_malloc

typedef mallocalloc _alloc;

#else

typedef defalloc _alloc;

#endif

templateclass ******alloc

static t* allocate()

static void deallocate(t* p, size_t n)

static void deallocate(t* p) };

void testalloc()

stl_construct.hpp

#pragma once

template inline void destroy(t* pointer)

template inline void construct(t1* p, const t2& value)

test.cpp

#include"stl_alloc.hpp"

#includeint main()

Bsp 空間分割模擬實現

bsp 二叉分割樹,在遊戲中用來分割區域性空間,方便碰撞檢測等的實現。下面介紹一種簡單易用的分割方法 分割步驟 一 將空間中的所有的面,加入的根部節點。二 遍歷根部節點的所有面,分別找到x y z的最大最小值,給根節點指定乙個合適的包圍空間。三 在這個節點的包圍空間裡找到最長軸 並按這個最長軸的中間...

web伺服器模擬實現

本文源於51cto。直接上 山寨 web伺服器 1 支援多個 瀏覽器訪問 多執行緒 2 如何提供服務 socket 3 如何返回響應 io author phenix public class tomcatserver 服務啟動方法 建立socket伺服器 public void start int...

list迭代器的模擬實現

namespace bite listnode ppre listnode pnext t val list 的迭代器 迭代器有兩種實現方式,具體應根據容器底層資料結構實現 1.原生態指標,比如 vector 2.將原生態指標進行封裝,因迭代器使用形式與指標完全相同,因此在自定義的類中必須實現以下方...