記憶體管理的目標是提供:
核心函式: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功能,通過手動呼叫記憶體管理方法進行實現 第二...