伺服器開發之記憶體<
一》 小片記憶體的管理
說個大白話: 乙個程式要執行起來,首先要從cpu
要首先從磁碟中把程式載入的到記憶體,當執行起來的時候,要從記憶體再到
cpu的快取,
cpu的快取還有多級,之所以硬體方面有這樣的設定,是因為他們之間每層之間的速度有著數量級的差別。
下面以三國殺的資料伺服器為例子說明伺服器記憶體的一些特點:
我簡稱為:sgs
<1> sgs資料伺服器的特點:
sgs的資料伺服器提供從資料庫載入和儲存玩家資料的功能,提供穩定,可靠,速度快的效能特點。
sgs使用者的資料特點,每個使用者有上百個物品,上百個戰功,幾十個任務,幾十個好友,等等一些屬性資料,乙個使用者平均有幾百個小的資料塊資訊。每個資料塊可能幾十個位元組到幾百個位元組不等。乙個資料伺服器提供兩萬個使用者的資料服務,那麼乙個邏輯程序大概要管理幾百萬個這樣的小資料塊。
sgs資料伺服器的另外乙個特點就是每秒種都有使用者不停的上線,下線,一天上下線的次數會有幾十萬次。
資料伺服器需要長時間的執行,一般會乙個月更新一次版本,當沒有版本更新的時候乙個月可能更長的時間是不需要重新啟動。
<2>sgs資料伺服器的上面這些特點,對記憶體方面的要求,必須是沒有記憶體的洩露,如果有記憶體的洩露,肯定是程式執行一段時間就會因為記憶體分配不到而發生宕機。造成玩家的資料丟失等嚴重事故。
<3> 我的解決方案。
考慮到sgs
資料伺服器的執行特點,我分析的是它的乙個執行週期的特點,乙個執行週期是乙個月。伺服器啟動後,在每天的乙個時間段會達到當天的人數高峰期,就好比餐館的午餐時間,肯定是餐館最繁忙,並非最好的時候。一直週末會的乙個時間,伺服器會達到這個周的最高峰,其實杭州的外婆家也是這樣,周五的晚上會是這週的最高峰,每個月新功能上線的當天,會是這個月的最高峰,好比我們的節假日,飯店,旅遊地區會達到這個執行週期的最高峰。
這些就是我們的資料伺服器在乙個執行週期裡面所要經歷的考驗,也是它的執行特點。
我說了,這麼多的廢話,落實到記憶體上,其實就是說每當我們的執行週期,出現這些高峰的時候也是我們記憶體需求最大的時候。
下面的圖是我所開發的資料伺服器的人數和所分配的記憶體對應圖示。你可以可以看到,這個記憶體模型是只分配不釋放的乙個模型。為什麼我會選擇這個的模型呢,當然了,這是資料伺服器的執行特點決定的,上面我簡單的說了一下資料伺服器乙個執行週期裡面的資料特點。那麼這種記憶體模型有什麼特點,或者說好處。種子模型會降低cpu
頻繁的出現分配和釋放記憶體的操作,降低因為程式的長期執行而增加記憶體碎片。會降低程序工作集的每日記憶體增量。
藍色表示伺服器所使用的記憶體,就是資料伺服器所分配的記憶體。
下面說說,這些記憶體的分配和管理是如何實現的:
這個類是整個系統的記憶體分配介面,系統所有的記憶體都必須從這裡分配出去,這個你可以新增記憶體的監控,統計,容錯等等介面。
這個介面只是提供了應用層的統一入口管理,下面說說如何實現底層的記憶體分配。因為sgs
資料伺服器管理的是數量比較多的小塊記憶體,所以我的處理是以最小單位為
4k進行分配,然後在以固定的大小分配成小塊小塊的記憶體,
class
xsmallblockmg
public:
xsmallblockmg( unsigned
int_blocksize,
unsigned
int_scmax_count,
unsigned
int_scstep=1000){}
~xsmallblockmg(void){}
char
* malloc();
void
free(char* pobj);
int gettotalcount(); //統計分配和管理的記憶體塊數目
//通用的分配池
typedef
char * ppuint;
typedef
map mapmempp;
class
cnormalallocxmg
protected:
cnormalallocxmg(){}
virtual ~cnormalallocxmg(){}
public:
static
cnormalallocxmg &single()
static
cnormalallocxmg
gsdllmg;
return
gsdllmg;
public:
char * malloc( unsigned
intma_size ){}
bool
free( char *pobj, int
marktype ){}
template
a>a *new_0xx(){}
template
a,typename
param0 >a *new_1xx( param0
param0 ){}
private:
mapmempp
m_map_pvoid; //用來檢查,防止重複釋放
// 小塊記憶體的大小
typedef
mapint,xsmallblockmg*> map_poolitem;
xsmallblockmg
用來管理單一大小的記憶體塊,比如長度32
個位元組長度的記憶體塊,這個物件負責管理在使用的和空閒的記憶體塊,當申請這個大小的記憶體塊不足夠使用的時候,就會申請新的記憶體,但申請後的記憶體是不會在釋放的。
cnormalallocxmg
是所有記憶體的申請入口,當我們申請乙個記憶體的時候,它會找到乙個大小最適合這個記憶體塊大小的
xsmallblockmg
物件來實現記憶體的分配,
cnormalallocxmg
裡面記憶體快的大小從8
,16,32,64,128,256,512,
這樣的大小遞增下去,當然你也可以根據你的邏輯資料的大小進行最合理的定製,在
sgs裡面最大的資料塊不大於
256,大部分在
32上下左右。
最後的注意:你可以新增你自己的介面函式,新增自己需要的功能,比如
(a): 新增乙個記憶體各種大小塊的統計功能,用來估計是否有記憶體洩漏,如果根據
(b): 需要注意的是,這個池的設計是不能中途對記憶體進行釋放的。這點請務必注意,如果你需要釋放,就需要你新增整塊的記憶體處理和管理。
伺服器開發 學習筆記 記憶體管理(記憶體池實現)
一 新建空的控制台專案 命名為hellomemory,新增標頭檔案walloc.h 還有乙個檔案walloc.cpp memorymgr.hpp walloc.h ifndef walloc h define walloc h void operator new size t size void o...
記一次伺服器記憶體報警的解決
週六的早晨收到伺服器記憶體告警郵件,嚇一大跳,趕緊爬起來,不然很嚴重的好嗎1 查出報警的記憶體目錄 命令 df h這樣原因就很清晰了,是伺服器的備份策略出現了問題。本應每隔七天備份這七天的日誌,現在是每分鐘都在備份這七天的日誌。很明顯是備份的定時任務cron語法使用錯誤。檢視伺服器備份定時指令碼 c...
記一則伺服器記憶體洩漏解決過程
很早之前用表弟的學生證薅了乙個阿里雲低配的主機,前段時間快到期也乙隻沒續費等到過期啦才想起來要續費,還好趕在伺服器資料清除之前續費成功,但當我登入到伺服器中發現有點卡不流暢這是什麼情況,而且發現伺服器中 docker 無法執行.當在伺服器執行 docker 時會抱如下錯誤 fatal error r...