在线亚洲黄色-在线亚洲观看-在线亚洲电影-在线亚洲成人-岛国大片在线观看免费版-岛国大片在线播放高清

LinuxMalloc分析從用戶空間到內核空間

導讀本文介紹malloc的實現及其malloc在進行堆擴展操作,并分析了虛擬地址到物理地址是如何實現映射關系。ordeder原創,原文鏈接:http://blog.csdn.net/ordeder/article/details/41654509。1背景知識;該結構是由進程task_struct.mm_struct進行管理的mm_struct的定義如下: 。1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;structmm_struct{。 ; ;structvm_area_struct*mmap; ;/*listofVMAs*/。 ; ;..。

系統大全為您提供本文介紹malloc的實現及其malloc在進行堆擴展操作,并分析了虛擬地址到物理地址是如何實現映射關系。ordeder原創,原文鏈接:http://blog.csdn.net/ordeder/article/details/416545091背景知識該結構是由進程task_struct.mm_struct進行管理的mm_struct的定義如下:??123456789101112131415structmm_struct{??structvm_area_struct*mmap;?/*listofVMAs*/??...??pgd_t*pgd;????????//用于地址映射??atomic_tmm_users;?????/*Howmanyuserswithuserspace?*/??atomic_tmm_count;?????/*Howmanyreferencesto"structmm_struct"(userscountas1)*/??intmap_count;???????/*numberofVMAs*/??...??//描述用戶空間的段分布:數據段,代碼段,堆棧段??unsignedlongstart_code,end_code,start_data,end_data;??unsignedlongstart_brk,brk,start_stack;??unsignedlongarg_start,arg_end,env_start,env_end;??unsignedlongRSS,total_vm,locked_vm;??...};??結構中的startxxx與endxxx描述了進程用戶空間數據段的所在地址。對于堆空間而言,start_brk是堆空間的起始地址,堆是向上擴展的。對于進程堆空間的擴展,brk來記錄堆的頂部位置。而進程動態申請的空間的已經使用到的地址空間(正在使用的變量)是被映射的,這些地址空間記錄于鏈表structvm_area_struct*mmap中。1.2地址映射虛擬地址和物理地址的映射:http://blog.csdn.net/ordeder/article/details/41630945?2malloc和freemalloc用于用戶空間堆擴展的函數接口。該函數是C庫,屬于封裝了相關系統調用(brk())的glibc庫函數。而不是系統調用(系統可沒有sys_malloc()。如果談及malloc函數涉及的系統內核的那些操作,那么總體可以分為用戶空間層面和內核空間層面來討論。2.1用戶層?malloc的源碼可見http://repo.or.cz/w/glibc.git/blob/HEAD:/malloc/malloc.cMalloc和free是在用戶層工作的,該接口為用戶提供一個比較方便管理堆的接口。它的主要工作是維護一個空閑的堆空間緩沖區鏈表。該緩沖區可以用如下數據結構表述:??123456789structmalloc_chunk{??INTERNAL_SIZE_Tprev_size;/*SizeofprevIoUschunk(iffree).*/??INTERNAL_SIZE_Tsize;/*Sizeinbytes,includingoverhead.*/??structmalloc_chunk*fd;/*doublelinks--usedonlyiffree.*/??structmalloc_chunk*bk;??/*Onlyusedforlargeblocks:pointertonextlargersize.*/??structmalloc_chunk*fd_nextsize;/*doublelinks--usedonlyiffree.*/??structmalloc_chunk*bk_nextsize;};?簡化版的空閑緩沖區鏈表如下所示,圖中head即為上述的malloc_chunk結構。而緊接著的size大小的內存區間是該chunk對應的數據區。?【malloc】每當進程調用malloc,首先會在該堆緩沖區尋找足夠大小的內存塊分配給進程(選擇緩沖區中的那個塊就有首次命中和最佳命中兩種算法)。如果freechunklist已無法滿足需求的chunk時,那么malloc會通過調用系統調用brk()將進程空間的堆進行擴展,在新擴展的堆空間上建立一個新的chunk并加入到freelist中,這個過程相當于進程批量想系統申請一塊內存(大小可能比實際需求大得多)。malloc返回的地址是chunk的中用于存儲數據的首地址,即:?chunk?+?sizeof(chunk)一個簡單的首次命中malloc的偽代碼:???1234567891011chunk?free_listmalloc(size)??foreach(chuck?in?freelist)????if(chunk.size?>size)??????return?chunk?+?sizeof(chunk)??//空閑緩沖區無法滿足需求,那么像系統批發內存??add?=?sys_brk(brk+(size?+sizeof(chunk)))??newchunk?=?(chunk)add;??newchunk.size?=?size;??...??return?newchunk?+?sizeof(newchunk)【free】free操作是對堆空間的回收,回收的區塊并不是立即返還給內核。而是將區塊對應的chunk“標記”為空閑,加入空閑隊列中。當然,如果空閑隊列中出現相鄰地址的chunk,那么可以考慮合并,已解決內存的碎片化,一遍滿足之后的大內存申請的需求。一個簡單的free偽代碼:將釋放的地址空間加入空閑鏈表中??123free(add)??pchunk?=?add?-?sizeof(chunk)??insert_to_freelist(pchunk)2.2?內核層?上文中,malloc的空閑chunk列表無法滿足用戶的需求,那么要通過sys_brk()進行堆的擴展,這時候才真正算得上進入內核空間。sys_brk()涉及的主要操作有:1.?在mm_struct中的堆上界brk延伸到newbrk:即申請一塊vma,vma.start=brk?vma.end=newbrk2.?為該虛擬區間塊進行物理內存的映射:從虛擬空間vma.start~vma.end中的每個內存頁進行映射:?12345addr?=?vma.startdo{??handle_mm_fault(mm,vma,addr,...)??addr?+=?PAGESIZE}while(addr>PAGE_SHIFT,同理,index后面補上12個0就是物理頁表的首地址。3.通過物理頁號,我們可以再內核中找到該物理頁的描述的指針mem_map[index]。Page結構可以參考http://blog.csdn.net/ordeder/article/details/41630945。?3總結?1Malloc和free怎么看著就是個用戶空間的內存池。特別free的實現。2堆的擴展依據brk的移動。Vm_area記錄了虛擬空間中已使用的地址塊。3每個進程的虛擬地址到物理地址的映射是有進程mm.pgd決定的,在該結構中記錄了虛擬頁號到物理頁號的映射關系。參考內核源碼情景分析http://blog.csdn.net/kobbee9/article/details/7397010http:///lib/view/open1409716051963.html附錄??123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110#definepgd_offset(mm,address)((mm)->pgd+pgd_index(address))inthandle_mm_fault(structmm_struct*mm,structvm_area_struct*vma,??unsignedlongaddress,intwrite_access){??intret=-1;??pgd_t*pgd;??pmd_t*pmd;???pgd=pgd_offset(mm,address);??pmd=pmd_alloc(pgd,address);???if(pmd){????pte_t*pte=pte_alloc(pmd,address);//pmd是空的,所以返回的是pgd[address]的pte項目????if(pte)??????ret=handle_pte_fault(mm,vma,address,write_access,pte);??}??returnret;}?//32位地址,pmd沒有意義externinlinepmd_t*pmd_alloc(pgd_t*pgd,unsignedlongaddress){??return(pmd_t*)pgd;}?//為address地址所在的頁構建pte索引項externinlinepte_t*pte_alloc(pmd_t*pmd,unsignedlongaddress){??address=(address>>PAGE_SHIFT)&(PTRS_PER_PTE-1);??if(pmd_none(*pmd)){????pte_t*page=get_pte_fast();?????if(!page)??????returnget_pte_slow(pmd,address);????pmd_set(pmd,page);????returnpage+address;??}??if(pmd_bad(*pmd)){????__bad_pte(pmd);????returnNULL;??}??return(pte_t*)__pmd_page(*pmd)+address;}?//為address對應的頁面分配物理頁面staticinlineinthandle_pte_fault(structmm_struct*mm,??structvm_area_struct*vma,unsignedlongaddress,??intwrite_access,pte_t*pte){??pte_tentry;??entry=*pte;??if(!pte_present(entry)){????...????if(pte_none(entry))??????returndo_no_page(mm,vma,address,write_access,pte);//缺頁,分配物理頁????...??}??...??return1;}??staticintdo_no_page(structmm_struct*mm,structvm_area_struct*vma,??unsignedlongaddress,intwrite_access,pte_t*page_table){??structpage*new_page;??pte_tentry;??//匿名(對于虛擬存儲空間而言)的物理映射??if(!vma->vm_ops||!vma->vm_ops->nopage)????returndo_anonymous_page(mm,vma,page_table,write_access,address);??//一下是文件的缺頁處理,在此不表??...}?//通過page指針,即可計算page的物理地址:物理地址=(page指針-mem_map)*頁大小+物理內存起始地址/*?*匿名映射,用于虛存到物理內存?*/staticintdo_anonymous_page(structmm_struct*mm,structvm_area_struct*vma,pte_t*page_table,intwrite_access,unsignedlongaddr){??structpage*page=NULL;??pte_tentry=pte_wrprotect(mk_pte(ZERO_PAGE(addr),vma->vm_page_prot));??if(write_access){????page=alloc_page(GFP_HIGHUSER);//從高端內存中分配內存????if(!page)??????return-1;????clear_user_highpage(page,addr);????entry=pte_mkwrite(pte_mkdirty(mk_pte(page,vma->vm_page_prot)));????mm->RSS++;????flush_page_to_ram(page);??}??set_pte(page_table,entry);//*page_table=entry;??/*Noneedtoinvalidate-itwasnon-presentbefore*/??update_mmu_cache(vma,addr,entry);??return1;?/*Minorfault*/}?#define__MEMORY_START???CONfig_MEMORY_START//物理內存中用于動態分配使用的起始地址voidflush_page_to_ram(structpage*pg){??unsignedlongphys;???/*Physicaladdressofthispage*/??phys=(pg-mem_map)*PAGE_SIZE+__MEMORY_START;??__flush_page_to_ram(phys_to_virt(phys));}?#define__virt_to_phys(vpage)((vpage)-PAGE_OFFSET+PHYS_OFFSET)#define__phys_to_virt(ppage)((ppage)+PAGE_OFFSET-PHYS_OFFSET)??以上就是系統大全給大家介紹的如何使的方法都有一定的了解了吧,好了,如果大家還想了解更多的資訊,那就趕緊點擊系統大全官網吧。本文來自系統大全http:///如需轉載請注明!推薦:win7純凈版

為你推薦
資訊專欄
熱門視頻
相關推薦
修復Win8電腦的7個問題辦法 nginx配置示例 Win81怎么設置默認瀏覽器Win81設置默認程序辦法 查看Linux下系統資源占用常用命令 linux中打包和壓縮的理解 linux命令之sort Linux下查找連接了mysql的進程 Linux下多線程排序的實現 linux下實現監控進程網絡帶寬 win8系統啟動時出現應用程序沖突怎么辦使用執 linuxtomcat一鍵維護腳本系 怎么樣查看Win81WinSxS文件夾實際大小 如何才能WPS快速輸入商標符號WPS快速輸入商標符 網易云音樂如何排序網易云音樂歌單排序的方 找回windows8命令提示符的辦法介紹 Win8遠程桌面登錄如何清除歷史痕跡 Linux011啟動流程分析 Win8系統怎么關閉smartscreen篩選器 win81自帶輸入法設置字體大小怎么樣改變方法 百度影音截圖保存在哪怎樣查找百度影音截圖 linux獲取daemon進程的控制臺數據 一個簡單的linux線程池 為什么win8設置了從不休眠還是休眠windows8取消休 Win8系統無法關閉后臺程序導致電腦卡的解決方法 有道云筆記如何找回被刪除的文件 win81系統怎樣設置滑動關機方法 Ubuntu時間管理 Linux文件lscpmvrm Windows81系統IE10瀏覽器如何去除超鏈接下劃線 Linux宕機后如何重啟最安全 linux下vi編輯器命令大全1 inux虛擬機網絡配制方法及遇到問題的解決方法 一樣的Windows8不一樣的概念圖 Win8系統中運行命令提示符的辦法 藍屏錯誤代碼是0x0000007F怎么辦 Win8創建圖片密碼與Pin碼 在GNULinux中查看端口占用情況的命令方法 怎么樣linux命令之halt命令 Ubuntu下的用戶和權限三 win8操作系統如何打開xv格式文件
Top 主站蜘蛛池模板: 亚洲图欧美| 久久久久国产一级毛片高清版 | 国产精品资源在线播放 | 精品精品国产高清a毛片牛牛 | 精品国产一区二区三区成人 | 一级毛片免费毛片一级毛片免费 | 国产日产精品_国产精品毛片 | 97日日碰人人模人人澡 | 欧美一级色图 | 国产欧美日韩在线播放 | 亚洲一区二区三区久久久久 | 国产免费高清 | 中文字幕精品一区二区精品 | 欧美亚洲综合另类在线观看 | 欧日韩视频 | 日韩在线观看视频免费 | 久久久青青久久国产精品 | 欧美视频一区二区三区 | 日韩有码电影 | 久久久香蕉| 日韩成人在线电影 | 欧美日韩免费看 | 青青热久久国产久精品秒播 | 亚洲欧美自拍一区 | 国产欧美日韩精品在钱 | 亚洲国产成人综合精品2020 | 亚洲一区二区三区在线免费观看 | 亚洲国产欧美91 | 在线观看国产一区二区三区 | 99国产精品一区二区 | 亚洲 欧美 日韩 另类 | 一区不卡在线观看 | 久久久久久综合一区中文字幕 | 国产69精品久久久久99不卡 | 中文国产成人精品少久久 | 青春草视频在线 | 成人欧美一区二区三区 | 91热国产| 高清国产美女一级a毛片 | 日韩一区二区视频 | 国产精品福利久久久久久小说 |