第21章 記憶體管理的設計與實現

2021-05-27 23:03:07 字數 4683 閱讀 8395

記憶體管理的目標是提供

核心函式:void *sys_malloc(unsigned long size); void *sys_free(void *);

系統呼叫函式 void * malloc(unsigned long size); void * free(void *);

記憶體管理

1、發現資源

2、監控資源--元資料記錄資源的屬性和標識

3、分配資源--修改元資料,返回資源的標識

4、**資源--修改元資料

記憶體的元資料

1、怎麼設計元資料

陣列 -- 方便查詢和分配(陣列元素是鍊錶,該鍊錶中的記憶體大小都是一樣的)

鍊錶 -- 方便分配和**

hash表

記憶體起始位址

記憶體大小

2、如何訪問元資料

不同格式的元資料造成元資料的大小、元資料的訪問方式、元資料的操作都不一樣

元資料存放的位置

訪問(共享、競爭)

設計思路

記憶體結構如下所示(mem.h源**)

#ifndef	    _mem_h_

#define _mem_h_

typedef struct memmem_t;

#define mem_free 0x0

#define mem_used 0x1

void init_mem(void);

void *sys_malloc(unsigned long size);

void *sys_free(void *addr);

#endif

記憶體元資料和它所描述的記憶體放在一起。假設os剛啟動時有63m(1m~64m)的空閒記憶體,要初始化記憶體管理。

free_mem_head = (mem_t *)1024*1024;

free_mem_head->hnext = free_mem_head->next = free_mem_head->hprev = free_mem_head->prev = null;

free_mem_head->size = 63*1024*1024 - sizeof(mem_t);

free_mem_head->flag = mem_free;

記憶體分配演算法是:
1、查詢合適大小的記憶體,並分配
記憶體**演算法是:
1、**記憶體,合併相鄰記憶體
具體演算法可以檢視

mem.c檔案的源**如下所示

#include "define.h"

#include "mem.h"

#include "kernel.h"

#include "video.h"

#include "mutex.h"

//位址方位描述符結構 address range descriptor structure

struct ards__attribute__((packed));

#define address_range_memory 1

#define address_range_reserved 2

//可用記憶體起始位址和大小

static unsigned long mem_start = 0;

static unsigned long mem_size = 0;

//未分配記憶體鍊錶,已分配記憶體鍊錶

static mem_t * free_mem_head = null;

static mem_t * used_mem_head = null;

//未分配記憶體hash表

#define mem_hash_nr 32

static mem_t * mem_hash[mem_hash_nr];

//初始化未分配記憶體鍊錶

mem_t * init_free_mem_head(unsigned long mem_start, unsigned long mem_size)

//給未分配記憶體鍊錶新增記憶體節點

mem_t *add_free_mem_head(mem_t * p)

else if(p < free_mem_head) //插在煉表頭

else //插在鍊錶中

p->next = pt->next;

if(p->next)

p->next->prev = p;

pt->next = p;

p->prev = pt;

}p->flag = mem_free;

return p;

}//從未分配記憶體鍊錶中摘下記憶體節點

mem_t * get_free_mem_head(mem_t * p)

else //鍊錶有多個節點

}else if(p->next == null) //摘取鍊錶尾

else //摘取鍊錶中的節點

return p;

}//把p記憶體空間分割成 size 和 (p->size - size - sizeof(mem_t))大小的兩個記憶體空間,然後摘除記憶體節點p

//返回(p->size - size - sizeof(mem_t))大小記憶體空間節點的指標

mem_t * split_get_free_mem_head(mem_t *p, unsigned long size)

//初始化已分配記憶體鍊錶

void init_used_mem_head()

//新增已分配記憶體節點到已分配記憶體鍊錶中 todo:以後再實現

mem_t *add_used_mem_head(mem_t * p)

//從已分配記憶體鍊錶中摘除已分配記憶體節點 todo:以後再實現

mem_t *get_used_mem_head(mem_t * p)

//初始化未分配記憶體hash表

void init_mem_hash()

}//把未分配的記憶體插入hash表中

mem_t * add_mem_to_hash(mem_t * mem)

else

return mem;

}//從hash表中獲得未分配記憶體,只要未分配的記憶體大小大於size

//成功則從hash表上摘除該記憶體!!!!!!!

//成功返回mem_t 指標,失敗返回null

mem_t * get_mem_from_hash(unsigned long size)

}return p;

}mem_t * remove_mem_from_hash(mem_t *p)

else if(p->hnext == null)

else

return p;

}//合併未分配記憶體

//成功則返回 合併後的mem_t記憶體節點指標

//該函式操作未分配記憶體鍊錶和記憶體hash表

mem_t *join_free_mem(mem_t *p)

if(p->next && (p + sizeof(mem_t) + p->size) == p->next) //合併右邊節點

return p;

}void init_mem()

}sys_kprint(char_attr(black,white),"\nmemory start = ");

print16base(char_attr(black,white),mem_start);

sys_kprint(char_attr(black,white),"\nmemory size = ");

print16base(char_attr(black,white),mem_size);

sys_kprint(char_attr(black,white),"\n\n");

//初始化未分配記憶體鍊錶和已分配記憶體鍊錶

mem_t *first_mem = null;

first_mem = init_free_mem_head(mem_start, mem_size);

init_used_mem_head();

//初始化未分配記憶體hash表

init_mem_hash();

//把第一塊未分配的記憶體新增進hash表中

add_mem_to_hash(first_mem);

}//獲取指定大小記憶體空間的位址,成功返回記憶體位址,失敗返回null

void *kmalloc(unsigned long size)

else

//新增到已分配記憶體鍊錶中

add_used_mem_head(p);

//從記憶體節點轉換成可用的記憶體指標

return ((void *)p + sizeof(mem_t));

}//釋放記憶體,成功則返回記憶體位址,失敗則返回null

void *kfree(void *addr)

mutex_t mem_mutex = 0;

void * sys_malloc(unsigned long size)

void * sys_free(void *addr)

第12章 段式記憶體管理

分頁式記憶體管理基本解決了交換記憶體管理的缺點,但自己本事也有缺點 基本無法進行共享記憶體,因為對乙個記憶體頁來說只要裡面有乙個位址不能共享,那整個頁就不能共享,日常中乙個記憶體頁中不能共享資料得位址是很常見的,所以分頁記憶體基本不能共享 那怎麼解決記憶體共享的問題呢 段氏記憶體管理 段氏記憶體管理...

第 8 章 記憶體管理策略

為了實現效能改進,應將多個程序儲存在記憶體中,也就是說必須共享記憶體。記憶體是現代計算機執行的核心。記憶體由乙個很大的位元組陣列來組成,每個位元組都有各自的位址。8.1.1 基礎硬體 cpu可以直接訪問的通用儲存只有記憶體和處理器內建的暫存器。每個程序都有乙個獨立的記憶體空間,可以保護程序不會互相影...

Objective C第2版第9章 記憶體管理

記憶體管理主要基於指標物件進行,作用於使用alloc new copy關鍵字建立的指標物件。withcapacity方法,或者別的方法建立的例項物件,無需進行記憶體管理,假設已經將計數器 1且設定為自動釋放。記憶體管理主要有2種方法實現 一種是禁用arc功能,通過手動呼叫記憶體管理方法進行實現 第二...