內存池的簡單實現c語言-創新互聯

內存池

內存池是為了解決大量malloc,free,導致的某些內存碎片。統一管理起來,比較方便。
基本思想是,根據要分配的內存,分為大塊內存和小塊內存。

創新互聯是一家專業提供深州企業網站建設,專注與成都網站建設、成都網站設計HTML5、小程序制作等業務。10年已為深州眾多企業、政府機構等服務。創新互聯專業的建站公司優惠進行中。
  1. 大塊內存直接用鏈表管理。
  2. 小塊內存,我這里設置為4k大小,內部再用一個一個小節點鏈表。
    大概的數據結構如下:
    在這里插入圖片描述
1.核心的數據結構
  1. 小片內存(4k以內)節點,第一個成員last, 是當前節點的首地址,end是指該4k內存的最后一段地址。

    struct  mp_node_s{unsigned char *last; //當前節點的位置
        unsigned char *end; //當前分配的內存(小于等于4k)最后一位
        struct mp_node_s *next;//指向下一個節點
        size_t failed=0;//失敗次數
    };
  2. 大片內存:

    struct mp_large_s{struct mp_large_s *next;//下個節點
        void *alloc;//分配的內存
    
    };
  3. 池節點:其其核心思想就是將分配的內存組織起來

    struct mp_pool_s {struct mp_large_s *large;
        struct mp_node_s *head;
        struct mp_node_s *current; //指向當前的節點
    
        int max;
    };
2. 流程
  1. 創建池,先創建出一個32位對齊的內存塊,這個內存塊是size大小,再加上mp_pool_s這個結構體的本身大小.
    在這里插入圖片描述

    #define MP_ALIGNMENT       		32
    #define MP_PAGE_SIZE			4096
    #define MP_MAX_ALLOC_FROM_POOL	(MP_PAGE_SIZE-1)
    
    struct mp_pool_s *mp_create_pool(size_t size) {struct mp_pool_s *p;
    	int ret = posix_memalign((void **)&p, MP_ALIGNMENT, size + sizeof(struct mp_pool_s) + sizeof(struct mp_node_s));
    	if (ret) {return NULL;
    	}
    	
    	p->max = (size< MP_MAX_ALLOC_FROM_POOL) ? size : MP_MAX_ALLOC_FROM_POOL;//小與4k,就用原本的大小,大于4k,那么限制為4k-1
    	p->current = p->head; //將當前結點指向池的頭部
    	p->large = NULL;
    
    	p->head->last = (unsigned char *)p + sizeof(struct mp_pool_s) + sizeof(struct mp_node_s); //當前頭部
    	p->head->end = p->head->last + size;
    
    	p->head->failed = 0;
    
    	return p;
    
    }
  2. 分配內存函數,分為,①分配大塊內存; ②分配小內存節點時,考慮兩種情況,小內存塊還夠用,小內存塊不夠用了,得分配新的小內存塊。

    void *mp_alloc(struct mp_pool_s *pool, size_t size) {unsigned char *m;
    	struct mp_node_s *p;
    //小于等于小內存塊大小的
    	if (size<= pool->max) {//就在當前節點后分配內存
    		p = pool->current;
    //遍歷當前節點后的節點,查找有沒有適合大小的內存塊
    		do {	
    			m = mp_align_ptr(p->last, MP_ALIGNMENT);
    	//分配范圍,依然還在內存塊范圍的,就不新分配新塊了,就地分配
    			if ((size_t)(p->end - m) >= size) {		p->last = m + size;
    				return m;
    			}
    			p = p->next;
    		} while (p);
    //沒有合適大小的內存塊,直接創建一塊新小內存塊
    		return mp_alloc_block(pool, size);
    	}
    //分配大塊內存
    	return mp_alloc_large(pool, size);
    	
    }
  3. 新建一個≤4k的小內存塊

在這里插入圖片描述

#define mp_align(n, alignment) (((n)+(alignment-1)) & ~(alignment-1))
#define mp_align_ptr(p, alignment) (void *)((((size_t)p)+(alignment-1)) & ~(alignment-1))

static void *mp_alloc_block(struct mp_pool_s *pool, size_t size) {

	unsigned char *m;//
	struct mp_node_s *h = pool->head; //頭部的小內存節點
	size_t psize = (size_t)(h->end - (unsigned char *)h); //獲取小內存塊大小
	//為m分配出一個內存
	int ret = posix_memalign((void **)&m, MP_ALIGNMENT, psize); //先分配出一個“頁”(<=4k)
	if (ret) return NULL;

	struct mp_node_s *p, *new_node, *current; 
	new_node = (struct mp_node_s*)m; //

	new_node->end = m + psize;
	new_node->next = NULL;
	new_node->failed = 0;
//在分配好的小內存塊中,分配一塊節點內存size
	m += sizeof(struct mp_node_s);
	m = mp_align_ptr(m, MP_ALIGNMENT);
	new_node->last = m + size; //last指向節點內存的末尾

	current = pool->current;
//遍歷當前節點后的節點,如果有失敗大于4次的節點,就把池的當前節點指向失敗大于4次的節點
//4是一個經驗值
	for (p = current; p->next; p = p->next) {
		if (p->failed++ >4) {
			current = p->next;
		}
	}
	p->next = new_node; //將最后一個結點的next指向新分配的內存塊

	pool->current = current ? current : new_node; 

	return m;

}
```
  1. 創建大塊內存,非常好理解,一個單鏈表,沒什么好說的

    static void *mp_alloc_large(struct mp_pool_s *pool, size_t size) {void *p = malloc(size); //直接分配內存
    	if (p == NULL) return NULL;
    
    	size_t n = 0;
    	struct mp_large_s *large;
    	for (large = pool->large; large; large = large->next) {if (large->alloc == NULL) {	large->alloc = p;
    			return p;
    		}
    		if (n ++ >3) break;
    	}
    //large結構體本身也是存在小內存塊里的
    	large = mp_alloc(pool, sizeof(struct mp_large_s));
    	if (large == NULL) {free(p);
    		return NULL;
    	}
    
    	large->alloc = p;
    	large->next = pool->large;
    	pool->large = large;
    
    	return p;
    }

你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧

網站標題:內存池的簡單實現c語言-創新互聯
瀏覽地址:http://m.kartarina.com/article22/ccgjcc.html

成都網站建設公司_創新互聯,為您提供營銷型網站建設網站建設網站排名定制網站建站公司面包屑導航

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都網頁設計公司
主站蜘蛛池模板: 熟妇人妻无码中文字幕老熟妇| 国产色综合久久无码有码 | 亚洲精品自偷自拍无码| 精品久久久无码21p发布| 亚洲精品无码mⅴ在线观看| 久久99久久无码毛片一区二区 | 人妻丰满熟妇AV无码区乱| 东京热一精品无码AV| 久久久久久久无码高潮| 国产AV天堂无码一区二区三区| 国产精品99精品无码视亚| 人妻无码aⅴ不卡中文字幕| 无码人妻丰满熟妇区BBBBXXXX| 国产成人无码网站| 亚洲AV无码之国产精品| 日本无码小泬粉嫩精品图| 久久精品无码中文字幕| 精品久久无码中文字幕| 亚洲国产a∨无码中文777| 国产精品亚洲一区二区无码| 亚洲精品无码久久久久久| 免费无码毛片一区二区APP| 亚洲国产精品无码专区影院| 中文精品无码中文字幕无码专区| 无码精品人妻一区二区三区AV| 亚洲AV日韩AV永久无码色欲| 中文字幕日产无码| 18精品久久久无码午夜福利| 亚洲AV日韩AV永久无码免下载| 精品无码一级毛片免费视频观看| 99久无码中文字幕一本久道| 波多野结衣VA无码中文字幕电影 | 日本无码色情三级播放| gogo少妇无码肉肉视频| 蕾丝av无码专区在线观看| 无码一区二区三区亚洲人妻| 国产精品爽爽va在线观看无码| 免费无码国产在线观国内自拍中文字幕 | 人妻在线无码一区二区三区 | yy111111少妇影院里无码| 无翼乌工口肉肉无遮挡无码18|