linux内存分配 连续 足够,linux内存池能分配连续物理内存吗
中。
size參數(shù):
內(nèi)核是基于頁(yè)技術(shù)分配內(nèi)存,以最佳的利用系統(tǒng)的RAM。
linux處理內(nèi)存分配的方法是:創(chuàng)建一系列的內(nèi)存對(duì)象池,每個(gè)池的內(nèi)存大小事固定的,處理分配請(qǐng)求時(shí),就直接在包含足夠大的內(nèi)存塊中傳遞一個(gè)整款給請(qǐng)求者。內(nèi)核只能分配一些預(yù)定義的固定大小的字節(jié)數(shù)組。kmalloc能處理的的最小內(nèi)存塊是32或者64,不大于128KB。
內(nèi)存區(qū)段:
linux內(nèi)核把內(nèi)存分為3個(gè)區(qū)段:可用于DMA的內(nèi)存,常規(guī)內(nèi)存以及高端內(nèi)存。kmalloc不能分配高端內(nèi)存。內(nèi)存區(qū)段在mm/page_alloc.c中實(shí)現(xiàn)。區(qū)段的初始化在對(duì)應(yīng)的arch樹(shù)下的mm/init.c中。
后備高速緩存 (lookaside cache)
內(nèi)核中普通對(duì)象進(jìn)行初始化所需的時(shí)間超過(guò)了對(duì)其進(jìn)行分配和釋放所需的時(shí)間,因此不應(yīng)該將內(nèi)存釋放回一個(gè)全局的內(nèi)存池,而是將內(nèi)存保持為針對(duì)特定目而初始化的狀態(tài)。例如,如果內(nèi)存被分配給了一個(gè)互斥鎖,那么只需在為互斥鎖首次分配內(nèi)存時(shí)執(zhí)行一次互斥鎖初始化函數(shù)(mutex_init)即可。后續(xù)的內(nèi)存分配不需要執(zhí)行這個(gè)初始化函數(shù),因?yàn)閺纳洗吾尫藕驼{(diào)用析構(gòu)之后,它已經(jīng)處于所需的狀態(tài)中了。
linux2.6中USB和SCSI驅(qū)動(dòng)程序使用了這種高速緩存,是為一些反復(fù)使用的塊增加某些特殊的內(nèi)存池。后背高速緩存管理也叫slab分配器,相關(guān)函數(shù)和類型在中申明。
slab分配器實(shí)現(xiàn)高速緩存具有kmem_cache_t類型。
kmem_cache_t * kmem_cache_create( const char *name, size_t size, size_t align,
unsigned long flags;
void (*constructor)(void*,kmem_cache_t *, unsigned long),
void (*destructor)(void*, kmem_cache_t *, unsigned long));
用于創(chuàng)建一個(gè)新的高速緩存對(duì)象。
constructor用于初始化新分配的對(duì)象,destructor用于清除對(duì)象。
一旦某個(gè)對(duì)象的高速緩存被創(chuàng)建以后,就可以調(diào)用kmem_cache_alloc從中分配內(nèi)存對(duì)象。
void * kmem_cache_alloc(kmem_cache_t *cache,int flags);
釋放內(nèi)存對(duì)象使用kmem_cache_free
void kmem_cache_free(kmem_cache_t *cache,const void *obj);
在內(nèi)存空間都被釋放后,模塊被卸載前,驅(qū)動(dòng)程序應(yīng)當(dāng)釋放他的高速緩存。
int kmem_cache_destory(kmem_cache_t *cache);
要檢查其返回狀態(tài),如果失敗,表明莫塊中發(fā)生了內(nèi)存泄露。
基于slab的高速緩存scullc
kmem_cache_t *scullc_cache;
scullc_cache=kmem_cache_creat("scullc",scullc_quantum,0,SLAB_HWCACHE_ALIGN,NULL,NULL);
if(!scullc_cache)
{
scullc_cleanup();
return -ENOMEM;
}
if(!dpte->data[s_pos])
{
dptr->data[s_pos]=kmem_cache_alloc(scullc_cache,GFP_KERNEL);
if(!dptr->data[s_pos])
goto nomem;
memset(dptr->data[s_pos],0,scullc_quantum);
}
for(i=0;idata[i])
kmem_cache_free(scullc_cache,dptr->data[i]);
}
if(scullc_cache)
kmem_cache_destory(scullc_cache);
內(nèi)存池:
內(nèi)核中有些地方的內(nèi)存分配是不允許失敗的,為確保能分配成功,內(nèi)核建立一種稱為內(nèi)存池的抽象,他試圖始終保持空閑狀態(tài),以便緊急情況使用。
mempool_t * mempool_creat(int min_nr,
mempool_alloc_t *alloc_fn, //對(duì)象分分配 mempool_alloc_slab
mempool_free_t *free_fn, //釋放 mempool_free_slab
void *pool_data);
可以用如下代碼來(lái)構(gòu)造內(nèi)存池
cache=kmem_cache_creat(...); //創(chuàng)建一個(gè)高速緩存
pool=mempool_creat(MY_POOL_MINIMUM,mempool_alloc_slab,mempool_free_slab,cache);//建立內(nèi)存池對(duì)象
void *mempool_alloc(mempool_t *poll,int gfp_mask);//分配對(duì)象
void *mempool_free(void *element,mempool_t *poll);//釋放對(duì)象
void mempool_destroy(mempool_t *poll);//銷毀內(nèi)存池
注意:mempool會(huì)分配一些內(nèi)存塊,空閑且不會(huì)被用到,造成內(nèi)存的大量浪費(fèi)。所以一般情況不要用內(nèi)存池。
總結(jié)
以上是生活随笔為你收集整理的linux内存分配 连续 足够,linux内存池能分配连续物理内存吗的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 打一个响指就那个灭霸是怎么得到这种力量的
- 下一篇: linux之父密码,Linux之父十大名