亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Linux Malloc分析-從用戶空間到內核空間

2019-11-09 18:30:06
字體:
來源:轉載
供稿:網友

本文介紹malloc的實現及其malloc在進行堆擴展操作,并分析了虛擬地址到物理地址是如何實現映射關系。 ordeder原創,原文鏈接: http://blog.csdn.net/ordeder/article/details/41654509

背景知識

進程的用戶空間

這里寫圖片描述

該結構是由進程task_struct.mm_struct進行管理的mm_struct的定義如下:

struct mm_struct { struct vm_area_struct * mmap; /* list of VMAs */ ... pgd_t * pgd; //用于地址映射 atomic_t mm_users; /* How many users with user space? */ atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */ int map_count; /* number of VMAs */ ... //描述用戶空間的段分布:數據段,代碼段,堆棧段 unsigned long start_code, end_code, start_data, end_data; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; unsigned long rss, total_vm, locked_vm; ... };

結構中的startxxx與endxxx描述了進程用戶空間數據段的所在地址。對于堆空間而言,start_brk是堆空間的起始地址,堆是向上擴展的。對于進程堆空間的擴展,brk來記錄堆的頂部位置。而進程動態申請的空間的已經使用到的地址空間(正在使用的變量)是被映射的,這些地址空間記錄于鏈表struct vm_area_struct * mmap中。

地址映射

虛擬地址和物理地址的映射 : http://blog.csdn.net/ordeder/article/details/41630945

malloc 和free

malloc用于用戶空間堆擴展的函數接口。該函數是C庫,屬于封裝了相關系統調用(brk())的glibc庫函數。而不是系統調用(系統可沒有sys_malloc()。如果談及malloc函數涉及的系統內核的那些操作,那么總體可以分為用戶空間層面和內核空間層面來討論。

用戶層

malloc 的源碼可見 http://repo.or.cz/w/glibc.git/blob/HEAD:/malloc/malloc.c

Malloc和free是在用戶層工作的,該接口為用戶提供一個比較方便管理堆的接口。它的主要工作是維護一個空閑的堆空間緩沖區鏈表。該緩沖區可以用如下數據結構表述:

struct malloc_chunk { INTERNAL_SIZE_T PRev_size; /* Size of previous chunk (if free). */ INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */ struct malloc_chunk* fd; /* double links -- used only if free. */ struct malloc_chunk* bk; /* Only used for large blocks: pointer to next larger size. */ struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */ struct malloc_chunk* bk_nextsize; };

簡化版的空閑緩沖區鏈表如下所示,圖中head即為上述的malloc_chunk結構。而緊接著的size大小的內存區間是該chunk對應的數據區。 這里寫圖片描述

【malloc】 每當進程調用malloc,首先會在該堆緩沖區尋找足夠大小的內存塊分配給進程(選擇緩沖區中的那個塊就有首次命中和最佳命中兩種算法)。如果freechunklist已無法滿足需求的chunk時,那么malloc會通過調用系統調用brk()將進程空間的堆進行擴展,在新擴展的堆空間上建立一個新的chunk并加入到freelist中,這個過程相當于進程批量想系統申請一塊內存(大小可能比實際需求大得多)。

malloc返回的地址是chunk的中用于存儲數據的首地址,即: chunk + sizeof(chunk)

這里寫圖片描述

一個簡單的首次命中malloc的偽代碼:

chunk free_list malloc(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偽代碼:將釋放的地址空間加入空閑鏈表中

free(add) pchunk = add - sizeof(chunk) insert_to_freelist(pchunk)

內核層

上文中,malloc的空閑chunk列表無法滿足用戶的需求,那么要通過sys_brk()進行堆的擴展,這時候才真正算得上進入內核空間。 sys_brk()涉及的主要操作有: 1. 在mm_struct中的堆上界brk延伸到newbrk:即申請一塊vma,vma.start=brk vma.end=newbrk 2. 為該虛擬區間塊進行物理內存的映射:從虛擬空間vma.start~vma.end中的每個內存頁進行映射:

addr = vma.start do{ handle_mm_fault(mm,vma,addr,...) addr += PAGESIZE }while(addr< vma.end)

函數handle_mm_fault為addr所在的內存頁映射物理頁面。實現虛擬空間到物理空間的換算和映射。

通過alloc_page申請一個物理頁面;換算addr在進程pdg映射中所在的pte地址;將addr對應的pte設置為物理頁面的首地址。 這里寫圖片描述

虛擬地址與物理地址

當進程讀取堆空間的地址vaddr時,虛擬地址vaddr到物理頁面的映射如下圖所示。 這里寫圖片描述

用戶空間的虛擬地址vaddr通過MMU(pgd,pmd,pte)找到對應的頁表項pte記錄的物理地址paddr頁表項paddr的高20位是物理頁號:index = x >> PAGE_SHIFT,同理,index后面補上12個0就是物理頁表的首地址。通過物理頁號,我們可以再內核中找到該物理頁的描述的指針mem_map[index]。Page結構可以參考http://blog.csdn.net/ordeder/article/details/41630945。

總結

Malloc 和 free 怎么看著就是個用戶空間的內存池。特別free的實現。堆的擴展依據brk的移動。Vm_area記錄了虛擬空間中已使用的地址塊。每個進程的虛擬地址到物理地址的映射是有進程mm.pgd決定的,在該結構中記錄了虛擬頁號到物理頁號的映射關系。

參考

內核源碼情景分析 http://blog.csdn.net/kobbee9/article/details/7397010 http://www.open-open.com/lib/view/open1409716051963.html

附錄

#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma, unsigned long address, int write_access) { int ret = -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); } return ret; } //32位地址,pmd沒有意義 extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address) { return (pmd_t *) pgd; } //為address地址所在的頁構建pte索引項 extern inline pte_t *pte_alloc(pmd_t *pmd, unsigned long address) { address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); if (pmd_none(*pmd)) { pte_t *page = get_pte_fast(); if (!page) return get_pte_slow(pmd, address); pmd_set(pmd,page); return page + address; } if (pmd_bad(*pmd)) { __bad_pte(pmd); return NULL; } return (pte_t *)__pmd_page(*pmd) + address; } //為address對應的頁面分配物理頁面 static inline int handle_pte_fault(struct mm_struct *mm, struct vm_area_struct * vma, unsigned long address, int write_access, pte_t * pte) { pte_t entry; entry = *pte; if (!pte_present(entry)) { ... if (pte_none(entry)) return do_no_page(mm, vma, address, write_access, pte);//缺頁,分配物理頁 ... } ... return 1; } static int do_no_page(struct mm_struct * mm, struct vm_area_struct * vma, unsigned long address, int write_access, pte_t *page_table) { struct page * new_page; pte_t entry; //匿名(對于虛擬存儲空間而言)的物理映射 if (!vma->vm_ops || !vma->vm_ops->nopage) return do_anonymous_page(mm, vma, page_table, write_access, address); //一下是文件的缺頁處理,在此不表 ... } //通過page指針,即可計算page的物理地址: 物理地址 = (page指針 - mem_map)* 頁大小 + 物理內存起始地址 /* * 匿名映射,用于虛存到物理內存 */ static int do_anonymous_page(struct mm_struct * mm, struct vm_area_struct * vma, pte_t *page_table, int write_access, unsigned long addr) { struct page *page = NULL; pte_t entry = 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; /* No need to invalidate - it was non-present before */ update_mmu_cache(vma, addr, entry); return 1; /* Minor fault */ } #define __MEMORY_START CONFIG_MEMORY_START //物理內存中用于動態分配使用的起始地址 void flush_page_to_ram(struct page *pg) { unsigned long phys; /* Physical address of this page */ 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)
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
色婷婷亚洲mv天堂mv在影片| 国产一级揄自揄精品视频| 国产丝袜精品第一页| 欧美激情视频免费观看| 不用播放器成人网| 最近2019中文免费高清视频观看www99| 国产精品精品视频| 韩国一区二区电影| 亚洲精品电影在线| 久久久久久久久久久av| 亚洲毛片在线观看| 精品一区电影国产| 亚洲第一精品福利| 欧美日韩国产丝袜另类| 九九热精品视频在线播放| 欧美日韩国产综合视频在线观看中文| 亚洲视频自拍偷拍| 亚洲视频在线免费观看| 久久久久久久久久久国产| 欧美性高跟鞋xxxxhd| www高清在线视频日韩欧美| 国产精品电影久久久久电影网| 中国日韩欧美久久久久久久久| 日韩中文字幕免费| 亚洲大胆美女视频| 成人中文字幕在线观看| 伊人成人开心激情综合网| 欧美俄罗斯乱妇| 69av视频在线播放| 成人精品一区二区三区电影免费| 91精品啪在线观看麻豆免费| 高跟丝袜欧美一区| 色99之美女主播在线视频| 国产精品久久久久久久久久三级| 亚洲国产成人一区| 亚洲一区二区三区四区视频| 精品国产乱码久久久久久天美| 日本成人精品在线| 中文字幕视频一区二区在线有码| 第一福利永久视频精品| 亚洲一区二区黄| 欧美乱大交xxxxx另类电影| 欧美成人sm免费视频| 亚洲欧美综合精品久久成人| 亚洲成人久久一区| 欧美丰满少妇xxxxx| 国产亚洲精品久久| 日本sm极度另类视频| 国产视频欧美视频| 久久久久北条麻妃免费看| 91爱爱小视频k| 精品无人国产偷自产在线| 国产欧美日韩免费看aⅴ视频| 精品国产一区二区三区四区在线观看| 亚洲天堂成人在线视频| 欧美插天视频在线播放| 中文字幕欧美日韩在线| 国产精品精品国产| 亚洲精品一区在线观看香蕉| 亚洲乱亚洲乱妇无码| 欧美日韩国产页| 亚洲第一精品夜夜躁人人躁| 欧美天堂在线观看| 亚洲丝袜在线视频| 国产精品欧美亚洲777777| 亚洲香蕉av在线一区二区三区| 亚洲国产古装精品网站| 亚洲国产欧美在线成人app| 精品自拍视频在线观看| 4k岛国日韩精品**专区| 成人激情春色网| 国产亚洲精品高潮| 精品日韩美女的视频高清| 久久精品欧美视频| 国产mv免费观看入口亚洲| 日韩视频在线免费观看| 国产精品三级在线| 国产成人精品视| 亚洲欧美精品伊人久久| 国产成人精品a视频一区www| 亚洲黄一区二区| 亚洲变态欧美另类捆绑| 国产视频久久网| 91精品国产综合久久香蕉922| 国产日韩欧美在线视频观看| 久久久999国产| 少妇精69xxtheporn| 6080yy精品一区二区三区| 国产精品偷伦一区二区| 日韩电影中文字幕av| 国产精品成人一区二区| 777午夜精品福利在线观看| 亚洲黄页网在线观看| 日韩麻豆第一页| 中文字幕日韩视频| xxxx性欧美| 美日韩精品免费观看视频| 性色av香蕉一区二区| 欧美放荡办公室videos4k| 欧美剧在线观看| 自拍亚洲一区欧美另类| 日韩中文娱乐网| 久久久久久一区二区三区| 精品国产视频在线| 亚洲国产高清自拍| 欧美精品videosex极品1| 国产精品稀缺呦系列在线| 国产精品偷伦免费视频观看的| 欧美最猛性xxxxx免费| 欧美国产亚洲视频| 97久久精品视频| 国产精品视频999| 精品久久久久久久久国产字幕| 中文在线资源观看视频网站免费不卡| 亚洲精品欧美极品| 亚洲最大的网站| 欧美精品电影免费在线观看| 精品久久久久久久久中文字幕| 精品中文字幕视频| 欧美在线激情视频| 伦伦影院午夜日韩欧美限制| 久久久精品一区二区三区| 91在线|亚洲| 国产成+人+综合+亚洲欧洲| 亚洲成人三级在线| 亚洲色图25p| 日韩美女在线观看| 性日韩欧美在线视频| 77777少妇光屁股久久一区| 国产mv免费观看入口亚洲| 性欧美暴力猛交69hd| 亚洲伦理中文字幕| 亚洲精品久久7777777| 国产精品免费视频久久久| 欧美午夜视频一区二区| 综合网中文字幕| 国产精品老牛影院在线观看| 国产日韩av在线播放| 国产va免费精品高清在线观看| 欧美有码在线视频| 日本成熟性欧美| 97久久超碰福利国产精品…| 日韩国产高清视频在线| 欧美极品少妇与黑人| 国产午夜精品一区理论片飘花| 亚洲永久在线观看| 日韩成人在线免费观看| 欧美日韩在线另类| 中文字幕亚洲欧美一区二区三区| 精品香蕉在线观看视频一| 国产精品久久久久久久久影视| 亚洲欧美一区二区精品久久久| 国产精品美女久久久免费| 亚洲欧美国产精品| 成人网在线免费观看| 97avcom| 韩日精品中文字幕| 97人洗澡人人免费公开视频碰碰碰| 欧美第一淫aaasss性| 国产精品视频在线观看| 狠狠干狠狠久久| 国产婷婷成人久久av免费高清| 91精品91久久久久久| 亚洲片国产一区一级在线观看|