Linux之内存描述符mm_struct

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏精讲JAVA

OutOfMemoryError异常系列之虚拟机栈和本地方法栈溢出

按照上一篇文章的分类,虚拟机栈与本地方法栈本应该分开讲,但是因为我用的虚拟机是Hotspot,虚拟机栈与本地方法栈为一个,所以,在此一起讲解。对于HotSpot...

1878
来自专栏木头编程 - moTzxx

PHP 生成随机码探索

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011415782/article/de...

822
来自专栏Golang语言社区

Go语言的管道Channel用法实例

本文实例讲述了Go语言的管道Channel用法。分享给大家供大家参考。具体分析如下: channel 是有类型的管道,可以用 channel 操作符 <- 对其...

3545
来自专栏技术小站

p=p+1与p++的区别

841
来自专栏Java技术栈

史上最全Java多线程面试题及答案

多线程并发编程是Java编程中重要的一块内容,也是面试重点覆盖区域。所以,学好多线程并发编程对Java程序员来来说极其重要的。 下面小编整理了60道最常见的Ja...

39111
来自专栏芋道源码1024

分布式作业 Elastic-Job-Lite 源码分析 —— 注册中心

ZookeeperRegistryCenter,基于 Zookeeper 注册中心。从上面的类图可以看到,ZookeeperRegistryCenter 实现 ...

972
来自专栏抠抠空间

Flask之WTForms

WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。

943
来自专栏性能与架构

快速理解linux文本分析利器awk

awk是什么 如果工作中需要操作linux比较多,那么awk是非常值得学习的 awk是一个极其强大的文本分析工具,把文件逐行的读入,以指定分隔符将每行切片,切...

3438
来自专栏小樱的经验随笔

汇编语言第三版答案(王爽)

汇编语言答案(王爽)  此文只是用来存个档,不喜勿喷 检测点1.1 (1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为 13位。 (2)1KB的存储器...

36711
来自专栏深度学习之tensorflow实战篇

hive排序:distribute by 、sort by 、cluster by 、order by 区别

 3 . 总结分析 1). order by 只有一个reduce负责对所有的数据进行排序,若大数据量,则需要较长的时间。建议在小的数据集中使用order b...

2524

扫码关注云+社区