Linux對於記憶體的管理涉及到非常多的方面,這篇文章首先從對進程虛擬地址空間的管理說起。(所依據的代碼是2.6.32.60) 無論是內核線程還是用戶進程,對於內核來說,無非都是task_struct這個數據結構的一個實例而已,task_struct被稱為進程描述符(process descripto ...
Linux對於記憶體的管理涉及到非常多的方面,這篇文章首先從對進程虛擬地址空間的管理說起。(所依據的代碼是2.6.32.60)
無論是內核線程還是用戶進程,對於內核來說,無非都是task_struct這個數據結構的一個實例而已,task_struct被稱為進程描述符(process descriptor),因為它記錄了這個進程所有的context。其中有一個被稱為'記憶體描述符‘(memory descriptor)的數據結構mm_struct,抽象並描述了Linux視角下管理進程地址空間的所有信息。 mm_struct定義在include/linux/mm_types.h中,其中的域抽象了進程的地址空間,如下圖所示:
1 struct mm_struct { 2 struct vm_area_struct * mmap; //指向虛擬區間(VMA)的鏈表 3 struct rb_root mm_rb; //指向線性區對象紅黑樹的根 4 struct vm_area_struct * mmap_cache; //指向最近找到的虛擬區間 5 unsigned long(*get_unmapped_area) (struct file *filp, 6 unsigned long addr, unsigned long len, 7 unsigned long pgoff, unsigned long flags);//在進程地址空間中搜索有效線性地址區 8 unsigned long(*get_unmapped_exec_area) (struct file *filp, 9 unsigned long addr, unsigned long len, 10 unsigned long pgoff, unsigned long flags); 11 void(*unmap_area) (struct mm_struct *mm, unsigned long addr);//釋放線性地址區間時調用的方法 12 unsigned long mmap_base; /* base of mmap area */ 13 unsigned long task_size; /* size of task vm space */ 14 15 unsigned long cached_hole_size; 16 unsigned long free_area_cache; //內核從這個地址開始搜索進程地址空間中線性地址的空閑區域 17 pgd_t * pgd; //指向頁全局目錄 18 atomic_t mm_users; //次使用計數器,使用這塊空間的個數 19 atomic_t mm_count; //主使用計數器 20 int map_count; //線性的個數 21 struct rw_semaphore mmap_sem; //線性區的讀/寫信號量 22 spinlock_t page_table_lock; //線性區的自旋鎖和頁表的自旋鎖 23 24 struct list_head mmlist; //指向記憶體描述符鏈表中的相鄰元素 25 26 /* Special counters, in some configurations protected by the 27 * page_table_lock, in other configurations by being atomic. 28 */ 29 mm_counter_t _file_rss; //mm_counter_t代表的類型實際是typedef atomic_long_t 30 mm_counter_t _anon_rss; 31 mm_counter_t _swap_usage; 32 33 unsigned long hiwater_rss; //進程所擁有的最大頁框數 34 unsigned long hiwater_vm; //進程線性區中最大頁數 35 36 unsigned long total_vm, locked_vm, shared_vm, exec_vm; 37 //total_vm 進程地址空間的大小(頁數) 38 //locked_vm 鎖住而不能換出的頁的個數 39 //shared_vm 共用文件記憶體映射中的頁數 40 41 unsigned long stack_vm, reserved_vm, def_flags, nr_ptes; 42 //stack_vm 用戶堆棧中的頁數 43 //reserved_vm 在保留區中的頁數或者在特殊線性區中的頁數 44 //def_flags 線性區預設的訪問標誌 45 //nr_ptes 進程的頁表數 46 47 unsigned long start_code, end_code, start_data, end_data; 48 //start_code 可執行代碼的起始地址 49 //end_code 可執行代碼的最後地址 50 //start_data已初始化數據的起始地址 51 // end_data已初始化數據的最後地址 52 53 unsigned long start_brk, brk, start_stack; 54 //start_stack堆的起始位置 55 //brk堆的當前的最後地址 56 //用戶堆棧的起始地址 57 58 unsigned long arg_start, arg_end, env_start, env_end; 59 //arg_start 命令行參數的起始地址 60 //arg_end命令行參數的起始地址 61 //env_start環境變數的起始地址 62 //env_end環境變數的最後地址 63 64 unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */ 65 66 struct linux_binfmt *binfmt; 67 68 cpumask_t cpu_vm_mask; //用於惰性TLB交換的位掩碼 69 /* Architecture-specific MM context */ 70 mm_context_t context; //指向有關特定結構體系信息的表 71 72 73 unsigned int faultstamp; 74 unsigned int token_priority; 75 unsigned int last_interval; 76 77 unsigned long flags; /* Must use atomic bitops to access the bits */ 78 79 struct core_state *core_state; /* coredumping support */ 80 #ifdef CONFIG_AIO 81 spinlock_t ioctx_lock; //用於保護非同步I/O上下文鏈表的鎖 82 struct hlist_head ioctx_list;//非同步I/O上下文 83 #endif 84 #ifdef CONFIG_MM_OWNER 85 struct task_struct *owner; 86 #endif 87 88 #ifdef CONFIG_PROC_FS 89 unsigned long num_exe_file_vmas; 90 #endif 91 #ifdef CONFIG_MMU_NOTIFIER 92 struct mmu_notifier_mm *mmu_notifier_mm; 93 #endif 94 #ifdef CONFIG_TRANSPARENT_HUGEPAGE 95 pgtable_t pmd_huge_pte; /* protected by page_table_lock */ 96 #endif 97 #ifdef __GENKSYMS__ 98 unsigned long rh_reserved[2]; 99 #else 100 //有多少任務分享這個mm OOM_DISABLE 101 union { 102 unsigned long rh_reserved_aux; 103 atomic_t oom_disable_count; 104 }; 105 106 /* base of lib map area (ASCII armour) */ 107 unsigned long shlib_base; 108 #endif 109 };
Reference:
http://www.cnblogs.com/Rofael/archive/2013/04/13/3019153.html
http://blog.csdn.net/persistence_s/article/details/70179419