1. 程式人生 > >一個最簡單的記憶體池AutoMemory

一個最簡單的記憶體池AutoMemory

    C/C++中記憶體管理是個最麻煩的事情,記憶體申請釋放,記憶體洩露,記憶體越界,甚至是記憶體碎片,就會導致程式出Core或者變慢。如何有效的管理記憶體,有很多方法,我認為最簡單的方式是用一個記憶體池來管理記憶體。

    談到記憶體池的時候,就有必要說下程式的生命週期和作用域,資料分為三類:1類是程序資料(全域性資料)。2、執行緒資料,每一個執行緒一份。3、請求資料,每一次呼叫一份。

        

    如果一個記憶體池想什麼生命週期和作用域的資料都放在裡面,可能是不合適的。所以我建議的使用方式是:程序一個記憶體池、每一個執行緒一個記憶體池、每個請求一個記憶體池。

    在程序/執行緒/請求初始時初始記憶體池,在程序/執行緒/請求結束時銷燬記憶體池。

    所以,就有了下面這個非常簡單的記憶體池了,程式碼有一點點繞,不過仔細閱讀還是能理解的。

    標頭檔案 AutoMemory.h

#ifndef _AUTO_MEMORY_H__
#define _AUTO_MEMORY_H__

#include <stddef.h>

//#define _MEM_TEST_
//#define _MEM_DEBUG_
#define _MEM_USE_

//default 1M
#define MEMORY_BLOCK_SIZE 1000000


/*
 * 執行緒相容,自動釋放
 */
class AutoMemory
{
public:
	AutoMemory();
	AutoMemory(int block_size);
	~AutoMemory();
	void* Alloc(size_t size);
	void Free(void* ptr);
	void FreeAll();

	void Debug();
	int BlockCount();
	size_t LeftSize();
	size_t MemSize();

private:
	struct MemBlock{
		MemBlock* prev;
	};
private:
	int headerSize;
	int blockSize;
	size_t memSize;
	int blockCount;
	char* begin;
	char* end;
	//MemBlock* currBlock;
};

#endif

   CPP檔案AutoMemory.cpp

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "AutoMemory.h"

AutoMemory::AutoMemory(){
	blockSize =  MEMORY_BLOCK_SIZE;
	blockCount = 0;
	memSize = 0;
	headerSize = sizeof(MemBlock);
	begin = end = ( char* ) headerSize;
}

AutoMemory::AutoMemory(int block_size){
	blockSize =  block_size;
	blockCount = 0;
	memSize = 0;
	headerSize = sizeof(MemBlock);
	begin = end = ( char* ) headerSize;
}

AutoMemory::~AutoMemory(){
	FreeAll();
}

size_t AutoMemory::MemSize(){
	return memSize;
}

int AutoMemory::BlockCount(){
	return blockCount;
}

size_t AutoMemory::LeftSize(){
	return (size_t)(end-begin);
}

void AutoMemory::Debug(){
	printf("Block count %d, Left size %d, Total size %d\n",
			this->BlockCount(),
			this->LeftSize(),
			this->MemSize() );
}

void* AutoMemory::Alloc(size_t size){
#ifndef _MEM_USE_
	return malloc(size);
#endif

	if ( (size_t)( end - begin ) < size ){
		if ( size >= blockSize){
			char* ptr = (char*)malloc(headerSize + size);
			MemBlock* pNew = (MemBlock*)ptr;
			MemBlock* pHeader = (MemBlock*)(begin - headerSize);
			if ( pHeader ){
				pNew->prev = pHeader->prev;
				pHeader->prev = pNew;
			}else{
				end = begin = (char*)( ptr + headerSize );
				pNew->prev = NULL;
			}
			blockCount += 1;
			memSize += size;
			return end;
		} else{
			char* ptr = (char*)malloc(headerSize + blockSize);
			MemBlock* pNew = (MemBlock*)ptr;
			pNew->prev = (MemBlock*)(begin - headerSize);
			begin = (char*)(ptr + headerSize);
			end = begin + blockSize;
			blockCount += 1;
			memSize += blockSize;

		}
	}
	return end -= size;
}

void AutoMemory::Free(void* ptr){
#ifndef _MEM_USE_
	free( ptr );
#endif
}

void AutoMemory::FreeAll(){
	MemBlock* pHeader = (MemBlock*)(begin - headerSize);
	while( pHeader ){
		MemBlock* pTemp = pHeader->prev;
        free( pHeader );
		pHeader = pTemp;
	}
	begin = end = (char*)headerSize;
	memSize = 0;
	blockCount = 0;
}

#ifdef _MEM_TEST_
int main(){
	AutoMemory am(100);
	printf("idx 1, alloc 10\n");
	char* buf = (char*)am.Alloc(10);
	am.Debug();

	printf("idx 2, alloc 90\n");
	am.Alloc(90);
	am.Debug();

	printf("idx 3, alloc 10\n");
	am.Alloc(10);
	am.Debug();

	printf("idx 4, alloc 100\n");
	am.Alloc(100);
	am.Debug();

	printf("idx 5, alloc 10\n");
	am.Alloc(10);
	am.Debug();
}
#endif





相關推薦

一個簡單記憶體AutoMemory

    C/C++中記憶體管理是個最麻煩的事情,記憶體申請釋放,記憶體洩露,記憶體越界,甚至是記憶體碎片,就會導致程式出Core或者變慢。如何有效的管理記憶體,有很多方法,我認為最簡單的方式是用一個記憶體池來管理記憶體。     談到記憶體池的時候,就有必要說下程式的生命週

python只使用Queue和Thread自己實現一個簡單的執行緒

        我的思路就是就是寫一個TifCutting類繼承自Thread,這個類裡有個屬性Queue;有一個addTask新增任務的方法,這個方法是把需要執行的函式放到Queue裡;因為繼承自Thread類,一定有一個重寫的run方法,這個方法是從自己的Queue屬性裡

一個簡單的gulp 實例

今天 blog png ruby 官網 base 1.0 pat fault 今天寫了一個簡單的gulp 實例 分享給大家! 比較適合gulp 初學者 首選: 看看gulp官網了解一些基本的定義    官網地址 : http://www.gulpjs.com.cn/ 搭建n

javaWeb之寫一個簡單的servlet

tran oid w3c write 分享 瀏覽器 servle code mapping 1. 創建一個類servletTest2 繼承HttpServlet類。 public class servletTest2 extends HttpServlet {

Go語言建立一個簡單的服務端點

一個 nds Coding port struct pac quest com handler handlers/handlers.go package handlers import ( "encoding/json" "net/http" )

一個簡單的cell按鈕點擊回調

eight property sin font 簡單的 cell 舉例 定義 ont 在cell.h定義 @property(nonatomic,strong)void(^pushType)(NSInteger); 在cell.m按鈕點擊時 _pushType(1);(舉

搭建一個簡單的node服務器

node string str console 參數 地址 param color json 搭建一個最簡單的node服務器   1、創建一個Http服務並監聽8888端口   2、使用url模塊 獲取請求的路由和請求參數 var http = require(‘

2018.3.29學習總結之如何運行一個簡單的Servlet程序

ati get png aid 父類 eclips 網上 自己 nco 1,我編寫了我的第一個Servlet程序。HelloServlet 繼承自HttpServlet。因此需要導入javax.servlet開頭的一系列包,那麽這些包來自哪裏呢?答案是Tomcat安裝目錄下

PHP分頁初探 一個簡單的PHP分頁代碼的簡單實現

too 查詢 use img 多少 contain 網站 實現 ice PHP分頁代碼在各種程序開發中都是必須要用到的,在網站開發中更是必選的一項。 要想寫出分頁代碼,首先你要理解SQL查詢語句:select * from goods limit 2,7。PHP分頁代碼核心

300行ABAP代碼實現一個簡單的區塊鏈原型

指向 repo 方法調用 輸入參數 transacti ui控件 挖礦 太多的 work 不知從什麽時候起,區塊鏈在網上一下子就火了。 這裏Jerry就不班門弄斧了,網上有太多的區塊鏈介紹文章。我的這篇文章沒有任何高大上的術語,就是300行ABAP代碼,實現一個最簡單的區

vue2 + iview-admin 1.3 + django 2.0 一個簡單的增刪改查例子

iview-admin axios django 前後端分離 api 以下為利用iview-admin + django 做的一個最基本的增刪改查例子。 前端iview-admin git clone https://github.com/iview/iview-admin.git cd

php+jquery+ajax+json的一個簡單實例

text serial OS .com min TP content meta 姓名 //網站 http://www.cnblogs.com/hjxcode/p/6029781.html<html><head><meta http-equiv=

java實現一個簡單的tomcat服務

連接數 accep print tex soc ins udp web服務 reply 1.如何啟動? main方法是程序的入口,tomcat也不例外,查看tomcat源碼,發現main是在Bootstrap 類中的; 2.如何建立連接? 要通訊,必須要建議so

IDEA新建一個簡單的Maven的JavaWeb項目

png conf onf 創建 edi 點擊 location 技術 lod 1.項目環境 IDEA:2016.2 JDK:1.8.0_76 Maven:3.2.5 2.File-->New-->Project-->Maven 3.選擇Proje

使用Django建立一個簡單的服務器

pytho eight 工程 django inf 新工程 加載 qlite sqlit Django作為python一個靈活性很強的網絡框架,在搭建服務器方面非常的方便,通過以下幾步就可以建立一個屬於自己的web服務器: 1.新建一個文件夾(盡量不要選擇在系統盤,在搭建虛

一文秒懂如何搭建一個簡單的充值系統

數據 一起 表示 存在 除了 社會 index 原因 必須 ? ???閱讀完本文大概需要5分鐘。 目錄 移動支付 微信支付 支付寶支付 充值體系 最基礎的架構 生產環境應用 總結 參考 ? ???一切都是生意。“天下熙熙皆為利來,天下攘攘皆為利往”。不知

Linux下一個簡單的不依賴第三庫的的C程式(1)

如下程式碼是一段彙編程式碼,雖然標題中使用了C語言這個詞語,但下面確實是一段彙編程式碼,弄清楚了這個程式碼,後續的知識點才會展開。 #PURPOSE: Simple program that exits and returns a # status code back to the Lin

VC++6.0下用60行程式寫成一個簡單的WEB伺服器

文章目錄 一個最簡單的WEB伺服器 HTTP 工作原理概述 HTTP協議通訊過程 源程式分析 過程 原始碼分析 原始碼60行(simplehttpserver.cpp) 編碼過程和

JS寫一個簡單的無縫輪播圖

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=d

一個簡單的程式讓你理解多徑通道

原文地址:https://wenku.baidu.com/view/f4bb76fe941ea76e58fa044d.html 時變、多徑是無線通道的特點,相信很多人在看了很多書之後,對無線通道感覺還是一頭霧水。為什麼多徑導致頻率選擇性?為什麼多普勒頻移反映了通道的時變性?對這些問題感覺困惑的肯