91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux內存申請是怎樣的

發布時間:2021-12-24 14:03:10 來源:億速云 閱讀:173 作者:iii 欄目:系統運維

本篇內容主要講解“Linux內存申請是怎樣的”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Linux內存申請是怎樣的”吧!

先上基礎,下圖是Linux的內存映射模型

  • 每一個進程都有自己的進程空間,進程空間的0-3G是用戶空間,3G-4G是內核空間

  • 每個進程的用戶空間不在同一個物理內存頁,但是所有的進程的內核空間對應同樣的物理地址

  • vmalloc分配的地址可以高端內存,也可以是低端內存

  • 0-896MB的物理地址是線性映射到物理映射區的。  

Linux內存申請是怎樣的

內存動態申請

和應用層一樣,內核程序也需要動態的分配內存,不同的是,內核進程可以控制分配的內存是在用戶空間還是內核空間,前者可以用于給用戶空間的堆區分配內存,eg,用戶進程的用戶空間的malloc最終就會通過系統調用回調內核空間的內存分配函數,此時該內存分配函數就屬于該用戶進程,可以給在該用戶進程的堆區分配空間并返回,最終使得一個用會進程在自己的用戶空間獲得內存分配;后者只在內核空間分配,所以用戶進程不能直接訪問該空間,所以多用在滿足內核程序自身的內存需求,下面是Linux內核空間申請內存常用API:

kmalloc - kfree

kmalloc申請的內存在物理內存上是連續的,他們與真實的物理地址只有一個固定的偏移,因此存在簡單的轉換關系。這個API 多用來申請不到一個page大小的內存。kmalloc的底層需要調用__get_free_pages,參數中表示內存類型的gtp_t flags正是這個函數的縮寫,常用的內存類型有GFP_USER,GFP_KERNEL,GFP_ATOMIC幾種。

  • GFP_USER表示為用戶空間頁分配內存,可以阻塞;

  • GFP_KERNEL是最常用的flag,注意,使用這個flag來申請內存時,如果暫時不能滿足,會引起進程阻塞,So,一定不要在中斷處理函數,tasklet和內核定時器等非進程上下文中使用GFP_KERNEL!!!

  • GFP_ATOMIC就可以用于上述三種情境,這個flag表示如果申請的內存不能用,則立即返回。

/**  * kmalloc - allocate memory  * @size: how many bytes of memory are required.  * @flags: the type of memory to allocate.  * The @flags argument may be one of:  * %GFP_USER - Allocate memory on behalf of user.  May sleep.  * %GFP_KERNEL - Allocate normal kernel ram.  May sleep.  * %GFP_ATOMIC - Allocation will not sleep.  May use emergency pools.  *   * For example, use this inside interrupt handlers.  */ void *kmalloc(size_t size, gfp_t flags); /**  * kfree - free previously allocated memory  * @objp: pointer returned by kmalloc.  * If @objp is NULL, no operation is performed.  */ void kfree(const void *objp);

同系列API還有

void *kzalloc(size_t size, gfp_t flags)

__get_free_pages - free_pages

__get_free_pages()與kmalloc()一樣是物理連續的內存,這一系列函數是Linux內核中***層的用于獲取空閑內存的方法,因為底層的buddy算法都是以(2^n)×PAGE_SIZE來管理內存的,所以他們總是以頁為單位分配內存的

unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order)  void free_pages(unsigned long addr, unsigned int order)

同系列API還有

unsigned long __get_free_page(gfp_t gfp)        unsigned long get_zeroed_page(gfp_t gfp_mask)    struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)
void free_page(unsigned long addr)

vmalloc - vfree

vmalloc在虛擬內存空間給出一塊連續的內存區,實質上,這片連續的虛擬內存在物理內存中并不一定連續,所以vmalloc申請的虛擬內存和物理內存之間也就沒有簡單的換算關系,正因如此,vmalloc()通常用于分配遠大于__get_free_pages()的內存空間,它的實現需要建立新的頁表,此外還會調用使用GFP_KERN的kmalloc,so,一定不要在中斷處理函數,tasklet和內核定時器等非進程上下文中使用vmalloc!

/**       * vmalloc  -  allocate virtually contiguous memory  * @size:          allocation size  * Allocate enough pages to cover @size from the page level allocator and map them into contiguous kernel virtual space.  */void *vmalloc(unsigned long size)   /**  *      vfree  -  release memory allocated by vmalloc()  *      @addr:          memory base address  */void vfree(const void *addr)

同系列的API還有

/**  * vmalloc_32  -  allocate virtually contiguous memory (32bit addressable)  * @size:          allocation size  * Allocate enough 32bit PA addressable pages to cover @size from the page level allocator and map them into contiguous kernel virtual space.  */void *vmalloc_32(unsigned long size)

slab緩存

我們知道,頁是內存映射的基本單位,但內核中很多頻繁創建的對象所需內存都不到一頁,此時如果仍然按照頁映射的方式,頻繁的進行分配和釋放就會造成資源的浪費,同時也會降低系統性能。為了解決的這樣的問題,內核引入了slab機制,使對象在前后兩次被使用時被分配在同一塊內存或同一類內存空間,且保留了基本的數據結構,就可以大大提高效率。kmalloc的底層即是使用slab算法管理分配的內存的。注意,slab依然是以頁為單位進行映射,只是映射之后分割這些頁為相同的更小的單元,從而節省了內存。slab分配的單元不能小于32B或大于128K。

/**  * kmem_cache_create - 創建slab緩存對象  * @name:slab緩存區名字,  * @size:slab分配的緩存區的每一個單元的大小  * @align:緩存區內存的對齊方式,一般給0  * @flags:控制分配的位掩碼,  * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5) to catch references to uninitialised memory.  * %SLAB_RED_ZONE - Insert `Red' zones around the allocated memory to check for buffer overruns.  * %SLAB_HWCACHE_ALIGN - Align the objects in this cache to a hardware cacheline.  This can be beneficial if you're counting cycles as closely as davem.  * %SLAB_CACHE_DMA - Use GFP_DMA memory  * %SLAB_STORE_USER - Store the last owner for bug hunting  *define SLAB_PANIC - Panic if kmem_cache_create() fails   */struct kmem_cache *kmem_cache_create(const char *name, size_t size, size_t align,unsigned long flags, void (*ctor)(void *))/**  * kmem_cache_alloc - Allocate an object from this cache.   * @cachep: The cache to allocate from.  * @flags: See kmalloc().  * The flags are only relevant if the cache has no available objects.  */void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags)  /**  * kmem_cache_free - Deallocate an object  * @cachep: The cache the allocation was from.  * @objp: The previously allocated object.  * Free an object which was previously allocated from this cache.  */void kmem_cache_free(struct kmem_cache *cachep, void *objp)  void kmem_cache_destroy(struct kmem_cache *s)

范例

//創建slab對象  struct kmem_cache_t *xj_sbcache; xj_sbcache = kmem_cache_create("xjslab",sizeof(struct xj_unit_t),0,SLAB_CACHE_DMA|SLAB_PANIC,NULL,NULL);//分配slab緩存  struct xj_unit_t *xj_unit; xj_unit = kmem_cache_alloc(xj_sbcache,GFP_KERNEL); /* 使用slab緩存 */ /* 釋放slab緩存 */  kmem_cache_free(xj_sbcache, xj_unit); /* 銷毀slab緩存 */  kmem_cache_destroy(xj_sbcache);

內存池

除了slab機制,內核還提供了傳統的內存池機制來管理小塊內存的分配。內存池主要是用來解決可能出現的內存不足的情況,因為一個內存池在創建的時候就已經分配好了一內存,當我們用mempool_alloc向一個已經創建好的內存池申請申請內存時,該函數首先會嘗試回調內存池創建時的分配內存函數,如果已經沒有內存可以分配,他就會使用內存池創建時預先分配的內存,這樣就可以避免因為無內存分配而陷入休眠,當然,如果預分配的內存也已經使用完畢,還是會陷入休眠。slab機制的目的是提高內存使用率以及內存管理效率,內存池的目的是避免內存的分配失敗。下面是內核中提供的關于內存池的API

/**       * mempool_create - create a memory pool  * @min_nr:    the minimum number of elements guaranteed to be  allocated for this pool.  * @alloc_fn:  user-defined element-allocation function.  * @free_fn:   user-defined element-freeing function.  * @pool_data: optional private data available to the user-defined functions.  *                * this function creates and allocates a guaranteed size, preallocated memory pool. The pool can be used from the mempool_alloc() and mempool_free() functions.   * This function might sleep. Both the alloc_fn() and the free_fn() functions might sleep - as long as the mempool_alloc() function is not called from IRQ contexts.  */ mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn, mempool_free_t *free_fn, void *pool_data)  /**       * mempool_alloc - allocate an element from a specific memory pool  * @pool:pointer to the memory pool which was allocated via mempool_create().  * @gfp_mask:  the usual allocation bitmask.  * this function only sleeps if the alloc_fn() function sleeps or returns NULL. Note that due to preallocation, this function never* fails when called from process contexts. (it might fail if called from an IRQ context.)  */      void * mempool_alloc(mempool_t *pool, gfp_t gfp_mask)      /**  * mempool_free - return an element to the pool.  * @element:   pool element pointer.  * @pool:pointer to the memory pool which was allocated via mempool_create().  *  * this function only sleeps if the free_fn() function sleeps.  */      void mempool_free(void *element, mempool_t *pool)      /**  * mempool_destroy - deallocate a memory pool  * @pool:pointer to the memory pool which was allocated via mempool_create().  *  * Free all reserved elements in @pool and @pool itself.  This function only sleeps if the free_fn() function sleeps.  */      void mempool_destroy(mempool_t *pool)

到此,相信大家對“Linux內存申請是怎樣的”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

稻城县| 黄冈市| 建德市| 永康市| 乳山市| 北安市| 望都县| 永平县| 忻城县| 高碑店市| 达孜县| 永嘉县| 中方县| 东城区| 龙门县| 祥云县| 鞍山市| 新安县| 尼勒克县| 商丘市| 田林县| 嘉义县| 三河市| 张家港市| 南安市| 周宁县| 友谊县| 常山县| 屯留县| 泽普县| 攀枝花市| 海丰县| 南部县| 县级市| 水城县| 东安县| 秦皇岛市| 都江堰市| 万荣县| 扶沟县| 靖西县|