一、进程地址空间
栈(stack),顶部的段,向下扩展。
主要保存本地变量、函数参数的栈帧(stack frame),一个新的帧在进入一个被调用函数时在栈顶被创建,然后在当前函数返回时销毁。
栈扩展过程中,如果地址未映射,则通过缺页异常处理。如果当前已没有空间可扩展,内核会向进程发送段错误。
mmap,从页缓存映射到进程地址空间。
进程可以调用mmap系统调用发起新的映射。
同时,linux内核也支持通过该段映射匿名内存。
堆(heap),为动态内存分配提供地址空间,这允许进程存储运行时数据。
进程镜像相关,BSS段、数据段和代码段
内核维护进程内存段的所有信息,并在内存描述符结构体中维护对应的转换表。
每个映射到虚拟地址空间的线性内存区域,都通过虚拟内存区间描述符(vm_area_struct)表示。
虚拟内存子系统维护一个虚拟内存区间(VMA)链表,每一个节点都代表一个虚拟地址段。
虚拟内存子系统需要在虚拟地址区域执行各种内存操作时,扫描vm_area链表。这些操作包括在已映射的地址段内查找特定的地址,或者追加一个代表新映射的虚拟地址区间(VMA)。
虚拟地址空间都是通过匿名内存映射分配的。虚拟地址子系统把进程的所有表示匿名内存区域放到一个链表里,并通过一个aon_vma类型的描述符来表示。
当一个进程fork分出一个子进程,调用者地址空间的所有匿名页都会以写时复制(COW)方式和子进程共享。这会导致要创建的VMA(为子进程)都会表示和父进程相同的匿名内存区域。为此,内存管理器需要定位并跟踪指向相同区域的所有VMA,这样才能支持取消映射和换出操作。虚拟地址子系统使用anon_vma_chain来链接一个进程组的所有anon_vma结构体。
二、管理虚拟内存区域
定位一个VMA:
find_vma函数查找VMA链表中,满足给定地址小于vma_area_struct:vm_end的首个VMA
合并VMA区域:
当一个新VMA被映射到现有的VMA之前或之后,并且和现有的VMA带有相同的访问属性,数据也是来自文件备份内存区域时,合并为一个VMA是更理想的。
vma_merge函数,合并带有相同属性的VMA
创建VMA:
do_mmap函数
删除VMA:
do_munmap函数
三、地址空间描述符(address_space)
一个缓存是用于特定需求的页集合。大多数操作系统都实现了缓冲区缓存(buffer cache),该缓存是一个管理内存块链表的框架,其内存块用于缓存持久性存储磁盘块。
缓冲区缓存允许文件系统通过将磁盘同步分组,并延迟到适当的时间来进行最小化磁盘IO操作。
linux内核实现了页缓存(page cache)来作为一种缓存机制。
页缓存是为了缓存磁盘文件和目录而被动态管理的页帧集合。
缓存中包含特定磁盘文件数据的页组是通过address_space机构体描述的
Linux虚拟内存管理
最新推荐文章于 2024-09-27 12:05:02 发布