linux内存分配 连续 足够,linux内存池能分配连续物理内存吗
中。
size參數:
內核是基于頁技術分配內存,以最佳的利用系統的RAM。
linux處理內存分配的方法是:創建一系列的內存對象池,每個池的內存大小事固定的,處理分配請求時,就直接在包含足夠大的內存塊中傳遞一個整款給請求者。內核只能分配一些預定義的固定大小的字節數組。kmalloc能處理的的最小內存塊是32或者64,不大于128KB。
內存區段:
linux內核把內存分為3個區段:可用于DMA的內存,常規內存以及高端內存。kmalloc不能分配高端內存。內存區段在mm/page_alloc.c中實現。區段的初始化在對應的arch樹下的mm/init.c中。
后備高速緩存 (lookaside cache)
內核中普通對象進行初始化所需的時間超過了對其進行分配和釋放所需的時間,因此不應該將內存釋放回一個全局的內存池,而是將內存保持為針對特定目而初始化的狀態。例如,如果內存被分配給了一個互斥鎖,那么只需在為互斥鎖首次分配內存時執行一次互斥鎖初始化函數(mutex_init)即可。后續的內存分配不需要執行這個初始化函數,因為從上次釋放和調用析構之后,它已經處于所需的狀態中了。
linux2.6中USB和SCSI驅動程序使用了這種高速緩存,是為一些反復使用的塊增加某些特殊的內存池。后背高速緩存管理也叫slab分配器,相關函數和類型在中申明。
slab分配器實現高速緩存具有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));
用于創建一個新的高速緩存對象。
constructor用于初始化新分配的對象,destructor用于清除對象。
一旦某個對象的高速緩存被創建以后,就可以調用kmem_cache_alloc從中分配內存對象。
void * kmem_cache_alloc(kmem_cache_t *cache,int flags);
釋放內存對象使用kmem_cache_free
void kmem_cache_free(kmem_cache_t *cache,const void *obj);
在內存空間都被釋放后,模塊被卸載前,驅動程序應當釋放他的高速緩存。
int kmem_cache_destory(kmem_cache_t *cache);
要檢查其返回狀態,如果失敗,表明莫塊中發生了內存泄露。
基于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);
內存池:
內核中有些地方的內存分配是不允許失敗的,為確保能分配成功,內核建立一種稱為內存池的抽象,他試圖始終保持空閑狀態,以便緊急情況使用。
mempool_t * mempool_creat(int min_nr,
mempool_alloc_t *alloc_fn, //對象分分配 mempool_alloc_slab
mempool_free_t *free_fn, //釋放 mempool_free_slab
void *pool_data);
可以用如下代碼來構造內存池
cache=kmem_cache_creat(...); //創建一個高速緩存
pool=mempool_creat(MY_POOL_MINIMUM,mempool_alloc_slab,mempool_free_slab,cache);//建立內存池對象
void *mempool_alloc(mempool_t *poll,int gfp_mask);//分配對象
void *mempool_free(void *element,mempool_t *poll);//釋放對象
void mempool_destroy(mempool_t *poll);//銷毀內存池
注意:mempool會分配一些內存塊,空閑且不會被用到,造成內存的大量浪費。所以一般情況不要用內存池。
總結
以上是生活随笔為你收集整理的linux内存分配 连续 足够,linux内存池能分配连续物理内存吗的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 打一个响指就那个灭霸是怎么得到这种力量的
- 下一篇: 52度锦上添花精酿价格五粮液