日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

kmalloc、vmalloc、malloc的区别

發布時間:2025/3/21 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 kmalloc、vmalloc、malloc的区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡單的說:

  • kmalloc和vmalloc是分配的是內核的內存,malloc分配的是用戶的內存
  • kmalloc保證分配的內存在物理上是連續的,vmalloc保證的是在虛擬地址空間上的連續,malloc不保證任何東西(這點是自己猜測的,不一定正確)
  • kmalloc能分配的大小有限,vmalloc和malloc能分配的大小相對較大
  • 內存只有在要被DMA訪問的時候才需要物理上連續
  • vmalloc比kmalloc要慢
  • ?

    詳細的解釋:

    ????? 對于提供了MMU(存儲管理器,輔助操作系統進行內存管理,提供虛實地址轉換等硬件支持)的處理器而言,Linux提供了復雜的存儲管理系統,使得進程所能訪問的內存達到4GB。

    ????? 進程的4GB內存空間被人為的分為兩個部分--用戶空間與內核空間。用戶空間地址分布從0到3GB(PAGE_OFFSET,在0x86中它等于0xC0000000),3GB到4GB為內核空間。

    ????? 內核空間中,從3G到vmalloc_start這段地址是物理內存映射區域(該區域中包含了內核鏡像、物理頁框表mem_map等等),比如我們使用 的 VMware虛擬系統內存是160M,那么3G~3G+160M這片內存就應該映射物理內存。在物理內存映射區之后,就是vmalloc區域。對于 160M的系統而言,vmalloc_start位置應在3G+160M附近(在物理內存映射區與vmalloc_start期間還存在一個8M的gap 來防止躍界),vmalloc_end的位置接近4G(最后位置系統會保留一片128k大小的區域用于專用頁面映射)

    ????? kmalloc和get_free_page申請的內存位于物理內存映射區域,而且在物理上也是連續的,它們與真實的物理地址只有一個固定的偏移,因此存在較簡單的轉換關系,virt_to_phys()可以實現內核虛擬地址轉化為物理地址:
    ?? #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
    ?? extern inline unsigned long virt_to_phys(volatile void * address)
    ?? {
    ??????  return __pa(address);
    ?? }
    上面轉換過程是將虛擬地址減去3G(PAGE_OFFSET=0XC000000)。

    與之對應的函數為phys_to_virt(),將內核物理地址轉化為虛擬地址:
    ?? #define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
    ?? extern inline void * phys_to_virt(unsigned long address)
    ?? {
    ??????  return __va(address);
    ?? }
    virt_to_phys()和phys_to_virt()都定義在include/asm-i386/io.h中。

    而vmalloc申請的內存則位于vmalloc_start~vmalloc_end之間,與物理地址沒有簡單的轉換關系,雖然在邏輯上它們也是連續的,但是在物理上它們不要求連續。

    我們用下面的程序來演示kmalloc、get_free_page和vmalloc的區別:
    #include <linux/module.h>
    #include <linux/slab.h>
    #include <linux/vmalloc.h>
    MODULE_LICENSE("GPL");
    unsigned char *pagemem;
    unsigned char *kmallocmem;
    unsigned char *vmallocmem;

    int __init mem_module_init(void)
    {
    //最好每次內存申請都檢查申請是否成功
    //下面這段僅僅作為演示的代碼沒有檢查
    pagemem = (unsigned char*)get_free_page(0);
    printk("<1>pagemem addr=%x", pagemem);

    kmallocmem = (unsigned char*)kmalloc(100, 0);
    printk("<1>kmallocmem addr=%x", kmallocmem);

    vmallocmem = (unsigned char*)vmalloc(1000000);
    printk("<1>vmallocmem addr=%x", vmallocmem);

    return 0;
    }

    void __exit mem_module_exit(void)
    {
    free_page(pagemem);
    kfree(kmallocmem);
    vfree(vmallocmem);
    }

    module_init(mem_module_init);
    module_exit(mem_module_exit);

    我們的系統上有160MB的內存空間,運行一次上述程序,發現pagemem的地址在0xc7997000(約3G+121M)、kmallocmem 地址在0xc9bc1380(約3G+155M)、vmallocmem的地址在0xcabeb000(約3G+171M)處,符合前文所述的內存布局。

    總結

    以上是生活随笔為你收集整理的kmalloc、vmalloc、malloc的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。