一、进程虚拟地址空间管理概览

二、mm_struct结构体的主要成员
| atomic_t mm_users; | 共享同一个用户虚拟地址空间的进程的数量,也就是线程组包含的进程的数量 |
| atomic_t mm_count; | 内存描述符的引用计数 |
| struct vm_area_struct *mmap; | 虚拟内存区域链表 |
| struct rb_root mm_rb; | 虚拟内存区域红黑树 |
| unsigned long (*get_unmapped_area) (struct file *filp, unsigned long addr, unsigned long len,unsigned long pgoff, unsigned long flags); | 在内存映射区域找到一个没有映射的区域 |
| pgd_t * pgd; | 指向页全局目录,即第一级页表 |
| unsigned long mmap_base; | 内存映射区域的起始地址 |
| unsigned long task_size; | 用户虚拟地址空间的长度 |
| unsigned long start_code, end_code; | 代码段的起始地址和结束地址 |
| unsigned long start_data, end_data; | 数据段的起始地址和结束地址 |
| unsigned long start_brk, brk; | 堆的起始地址和结束地址 |
| unsigned long start_stack; | 栈的起始地址 |
| unsigned long arg_start, arg_end; | 参数字符串的起始地址和结束地址 |
| unsigned long env_start, env_end; | 环境变量的起始地址和结束地址 |
| mm_context_t context; | 处理器架构特定的内存管理上下文 |

三、mm和active_mm
在进程的task_struct结构体中包含两个指向mm_struct结构的指针:
struct task_struct
{
// ...
struct mm_struct *mm;//内核线程没有用户虚拟地址空间,所以内核线程这个值为空
struct mm_struct *active_mm;//进程的active_mm和mm总是指向同一个内存描述符。内核线程的active_mm在没有运行时是空指针,在运行时指向从上一个进程借用的内存描述符
// ...
};
如果进程不属于线程组,进程描述符的成员mm和active_mm都指向同一个内存描述符,内存描述符的成员mm_users是1、成员mm_count是1。
如果两个进程属于同一个线程组,每个进程的进程描述符的成员mm和active_mm都指向同一个内存描述符,内存描述符的成员mm_users是2、成员mm_count是1。
内核线程的mm始终为空。当内核线程没有运行时,active_mm为空,当内核线程运行时,借用上一个进程的内存描述符,在被借用进程的用户虚拟地址空间的上方运行,进程描述符的成员active_mm指向借用的内存描述符,假设被借用的内存描述符所属的进程不属于线程组,那么内存描述符的成员mm_users不变,仍然是1,成员mm_count加1变成2。
ref:
Linux的进程地址空间[三] - 知乎
进程—内存描述符(mm_struct)_宇哲_安菲尔德的博客-CSDN博客_mm_struct
mm_struct(内存描述符) - CodeAntenna
mm_struct(内存描述符)_zcl9796的博客-CSDN博客_mm_struct
Linux 内核 | 内存管理——Slab 分配器 - 一丁点儿
《linux内核深度解析-基于ARM64架构的Linux 4.x内核》


![[附源码]Python计算机毕业设计红旗家具城管理系统Django(程序+LW)](https://img-blog.csdnimg.cn/648ac3698618429da7dd4cf79e195644.png)





![[附源码]Node.js计算机毕业设计公交电子站牌管理系统软件Express](https://img-blog.csdnimg.cn/6454cf3ccfdc4e479a580031f3e2c507.png)







![[附源码]Python计算机毕业设计Django课程在线测评系统](https://img-blog.csdnimg.cn/5be1f063095c42158f7b3296cc4b6755.png)


