mm_struct简介

本文介绍了Linux内核中的mm_struct结构,它是用于描述进程虚拟地址空间的关键数据结构。每个进程有一个mm_struct,包含页目录指针、虚拟区间描述符vm_area_struct的链表或红黑树,以及用于同步和计数的信号量。vm_area_struct表示虚拟空间的特定区域,而vm_operations_struct定义了在这些区域上的操作,如打开、关闭和处理缺页异常。
摘要由CSDN通过智能技术生成

一、什么是mm_struct???
内存描述符也用一个结构体表示,这个结构体的名字叫做mm_struct(内存描述符),linux就是通过mm_struct这个结构体来实现内存管理。 一个进程的虚拟地址空间主要由两个数据结构来描述,一个是最高层次的mm_struct,一个是较高层次的vm_ares_struct。最高层次的mm_struct结构描述了一个进程的整个虚拟地址空间。较高层次的结构vm_area_struct描述了虚拟地址空间的一个区间(简称虚拟区)。每个进程只有一个mm_struct结构,在每个进程的task_struct结构体中,有一个指向该进程的结构。可以说,mm_struct结构是对整个用户空间的描述。
在进程的task_struct结构体中包含一个指向mm_struct结构的指针,mm_struct用来描述一个进程的虚拟地址空间。进程的mm_struct则包含装入的可执行映像信息以及进程的页目录指针pgd。该结构还包含有指向vm_area_struct结构的几个指针,每个vm_area_struct代表进程的一个虚拟地址区间。vm_area_struct结构含有指向vm_operations_struct结构的一个指针,vm_operations_struct描述了在这个区间的操作。vm_operations_struct结构中包含的是函数指针,其中open、close分别用于虚拟区间的打开、关闭,而nopage用于当虚拟页面不再物理内存而引起的”缺页异常”时所调用的函数,当linux处理这一缺页异常时,就可以为新的虚拟内存分配实际的物理内存。

下面的linux管理内存的大致结构:
这里写图片描述

二、mm_struct
每个进程都只有一个内存描述符mm_struct。在每个进程的task_struct结构中,有一个指向mm_struct的变量,这个变量常常是mm。
mm_struct是对进程的地址空间(虚拟内存)的描述。一个进程的虚拟空间中可能有多个虚拟区间,对这些虚拟空间的组织方式有两种,当虚拟区较少时采用单链表,由mmap指针指向这个链表,当虚拟区间多时采用红黑树进行管理,由mm_rb指向这棵树。因为程序中用到的地址常常具有局部性,因此,最近一次用到的虚拟区间很可能下一次还要用到,因此把最近用到的虚拟区间结构放到高速缓存,这个虚拟区间就由mmap_cache指向。
指针pgt指向该进程的页目录(每个进程都有自己的页目录),当调度程序调度一个程序运行时,就将这个地址转换成物理地址,并写入控制寄存器。
由于进程的虚拟空间及下属的虚拟区间有可能在不同的上下文中受到访问,而这些访问又必须互斥,所以在该结构中设置了用于P,V操作的信号量mmap_sem。此外,page_table_lock也是为类似的目的而设置。
虽然每个进程只有一个虚拟空间,但是这个虚拟空间可以被别的进程来共享。如:子进程共享父进程的地址空间,而mm_user和mm_count就对其计数。
另外,还描述了代码段、数据段、堆栈段、参数段及环境段的起始和结束地址。

st
mm_structLinux内核中用于管理进程地址空间的数据结构,它定义在<linux/mm_types.h>头文件中。 该结构体的定义包括了进程的许多重要信息,如进程的内存映射表,虚拟地址空间的大小,以及进程的用户态和内核态栈等。它还包含了指向进程地址空间的pgd指针,以及指向内存管理器的指针,用于在内存不足时分配和回收进程的物理内存mm_struct结构体的定义如下: ``` struct mm_struct { struct vm_area_struct *mmap; /* 进程的内存映射表 */ struct rb_root mm_rb; /* 虚拟地址区间红黑树 */ struct vm_area_struct *mmap_cache; /* 最近使用的内存映射 */ 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; /* 进程环境变量的开始和结束地址 */ unsigned long saved_auxv[AT_VECTOR_SIZE]; /* 辅助向量 */ pgd_t *pgd; /* 进程的页表指针 */ atomic_t mm_users; /* 进程共享该地址空间的用户数 */ atomic_t mm_count; /* 进程共享该地址空间的引用计数 */ int map_count; /* 进程内存映射表中的区间数 */ spinlock_t page_table_lock; /* 页表锁 */ struct rw_semaphore mmap_sem; /* 内存映射表锁 */ struct list_head mmlist; /* 进程地址空间的链表 */ unsigned long hiwater_rss; /* 进程使用的最大物理内存 */ unsigned long hiwater_vm; /* 进程使用的最大虚拟内存 */ unsigned long total_vm; /* 进程使用的总虚拟内存 */ unsigned long locked_vm; /* 进程使用的锁定虚拟内存 */ unsigned long pinned_vm; /* 进程使用的固定虚拟内存 */ unsigned long data_vm; /* 进程使用的数据段虚拟内存 */ unsigned long exec_vm; /* 进程使用的可执行代码段虚拟内存 */ unsigned long stack_vm; /* 进程使用的用户态栈虚拟内存 */ unsigned long def_flags; /* 进程缺省的内存映射标志 */ unsigned long nr_ptes; /* 进程使用的页表条目数 */ unsigned long nr_pmds; /* 进程使用的页中页条目数 */ unsigned long nr_puds; /* 进程使用的页上页条目数 */ unsigned long nr_p4ds; /* 进程使用的页上页上页条目数 */ struct task_struct *owner; /* 拥有该地址空间的进程 */ struct file *exe_file; /* 执行文件的文件指针 */ }; ``` 在进程创建时,Linux内核会为该进程分配一个新的mm_struct结构体,并初始化其中的各个字段。当进程调用fork()函数创建子进程时,子进程会共享父进程的mm_struct结构体,使得子进程和父进程共享同一个虚拟地址空间。在进程结束时,Linux内核会回收该进程的mm_struct结构体及其相关资源。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值