這篇文章給大家介紹如何理解Linux進程的內存管理,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
創新互聯公司主要從事成都網站設計、成都做網站、網頁設計、企業做網站、公司建網站等業務。立足成都服務婁底,十余年網站建設經驗,價格優惠、服務專業,歡迎來電咨詢建站服務:13518219792
一個進程的虛擬地址空間主要由兩個數據結來描述,一個是 mm_struct,一個是 vm_area_structs。
mm_struct結構描述了一個進程的整個虛擬地址空間,vm_area_truct描述了虛擬地址空間的一個區間(簡稱虛擬區)。下圖就是我們所說的由task_struct到mm_struct,進程的地址空間的分布。
每一個進程都會有自己獨立的mm_struct,這樣每一個進程都會有自己獨立的地址空間,這樣才能互不干擾。當進程之間的地址空間被共享的時候,我們可以理解為這個時候是多個進程使用一份地址空間,這就是線程。
struct mm_struct { struct vm_area_struct *mmap; //指向虛擬區間(VMA)鏈表 struct rb_root mm_rb; //指向red_black樹 struct vm_area_struct *mmap_cache; //找到最近的虛擬區間 unsigned long(*get_unmapped_area)(struct file *filp,unsigned long addr,unsigned long len,unsigned long pgoof,unsigned long flags); void (*unmap_area)(struct mm_struct *mm,unsigned long addr); unsigned long mmap_base; unsigned long task_size; //擁有該結構體的進程的虛擬地址空間的大小 unsigned long cached_hole_size; unsigned long free_area_cache; pgd_t *pgd; //指向頁全局目錄 atomic_t mm_users; //用戶空間中有多少用戶 atomic_t mm_count; //對"struct mm_struct"有多少引用 int map_count; //虛擬區間的個數 struct rw_semaphore mmap_sem; spinlock_t page_table_lock; //保護任務頁表和mm->rss struct list_head mmlist; //所有活動mm的鏈表 mm_counter_t _file_rss; mm_counter_t _anon_rss; unsigned long hiwter_rss; unsigned long hiwater_vm; unsigned long total_vm,locked_vm,shared_vm,exec_vm; usingned long stack_vm,reserved_vm,def_flags,nr_ptes; unsingned long start_code,end_code,start_data,end_data; //代碼段的開始start_code ,結束end_code,數據段的開始start_data,結束end_data unsigned long start_brk,brk,start_stack; //start_brk和brk記錄有關堆的信息,start_brk是用戶虛擬地址空間初始化,brk是當前堆的結束地址,start_stack是棧的起始地址 unsigned long arg_start,arg_end,env_start,env_end; //參數段的開始arg_start,結束arg_end,環境段的開始env_start,結束env_end unsigned long saved_auxv[AT_VECTOR_SIZE]; struct linux_binfmt *binfmt; cpumask_t cpu_vm_mask; mm_counter_t context; unsigned int faultstamp; unsigned int token_priority; unsigned int last_interval; unsigned long flags; struct core_state *core_state; }
分配的每個虛擬內存區域都由一個vm_area_struct 數據結構來管理,包括虛擬內存的起始和結束地址,以及內存的訪問權限等,通常命名為vma;vm_area_struct 數據結構的定義如下:
struct vm_area_struct { /* The first cache line has the info for VMA tree walking. 第一個緩存行具有VMA樹移動的信息*/ unsigned long vm_start; /* Our start address within vm_mm. */ unsigned long vm_end; /* The first byte after our end address within vm_mm. */ /* linked list of VM areas per task, sorted by address 每個任務的VM區域的鏈接列表,按地址排序*/ struct vm_area_struct *vm_next, *vm_prev; struct rb_node vm_rb; /* 此VMA左側最大的可用內存間隙(以字節為單位)。 在此VMA和vma-> vm_prev之間, 或者在VMA rbtree中我們下面的一個VMA與其->vm_prev之間。 這有助于get_unmapped_area找到合適大小的空閑區域。 */ unsigned long rb_subtree_gap; /* Second cache line starts here. 第二個緩存行從這里開始*/ struct mm_struct *vm_mm; /* 我們所屬的address space*/ pgprot_t vm_page_prot; /* 此VMA的訪問權限 */ unsigned long vm_flags; /* Flags, see mm.h. */ /* 對于具有地址空間(address apace)和后備存儲(backing store)的區域, 鏈接到address_space->i_mmap間隔樹,或者鏈接到address_space-> i_mmap_nonlinear列表中的vma。 */ union { struct { struct rb_node rb; unsigned long rb_subtree_last; } linear; struct list_head nonlinear; } shared; /* 在其中一個文件頁面的COW之后,文件的MAP_PRIVATE vma可以在i_mmap樹和anon_vma列表中。 MAP_SHARED vma只能位于i_mmap樹中。 匿名MAP_PRIVATE,堆棧或brk vma(帶有NULL文件)只能位于anon_vma列表中。 */ struct list_head anon_vma_chain; /* Serialized by mmap_sem & * page_table_lock 由mmap_sem和* page_table_lock序列化*/ struct anon_vma *anon_vma; /* Serialized by page_table_lock 由page_table_lock序列化*/ /* 用于處理此結構體的函數指針 */ const struct vm_operations_struct *vm_ops; /* 后備存儲(backing store)的信息: */ unsigned long vm_pgoff; /* 以PAGE_SIZE為單位的偏移量(在vm_file中),*不是* PAGE_CACHE_SIZE*/ struct file * vm_file; /* 我們映射到文件(可以為NULL)*/ void * vm_private_data; /* 是vm_pte(共享內存) */ #ifndef CONFIG_MMU struct vm_region *vm_region; /* NOMMU映射區域 */ #endif #ifdef CONFIG_NUMA struct mempolicy *vm_policy; /* 針對VMA的NUMA政策 */ #endif };
insmod test.ko pid_mem=3253 顯示各個vma區域
cat /proc/3253/maps 顯示各個vma區域
看下兩種方式的對比:
關于如何理解Linux進程的內存管理就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
網頁題目:如何理解Linux進程的內存管理
網址分享:http://vcdvsql.cn/article46/pphieg.html
成都網站建設公司_創新互聯,為您提供微信小程序、標簽優化、ChatGPT、定制開發、網頁設計公司、
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯