Linux 内核的内存管理探秘之四 虚拟内存的管理
Linux 操作系统中,内存管理是非常重要的一部分。虚拟内存技术是现代操作系统中的一个关键技术,它克服了旧有的内存管理的限制,允许系统运行比物理内存大的应用程序,同时也允许把暂时不用的页交换到磁盘,从而得到更多的可用内存。本文将深入剖析 Linux 内核的虚拟内存管理机制。
一、概述
虚拟内存是指系统使用部分硬盘空间充当内存使用,使系统能够提供比实际大得多的内存,可以运行比物理内存大的程序。虚拟内存技术实现了以下功能:
1. 系统可以运行比实际内存大的程序;
2. 程序不必一次性全部装入内存,而是需要时装入内存;
3. 进程间的内存共享;
4. 内存保护。
二、虚拟内存的管理
虚拟内存技术的实现需要硬件支持和软件机制。i386 的分页技术和页异常机制为虚存技术的实现提供了硬件支持。软件机制包括按需分页、写时复制、页交换等。
2.1 请求调页(Paging On Command)
请求调页是指当创建新进程后, 只是分配好进程的线性地址空间(生成虚存区 vm_area_struct 的链表),并不立即分配实际的物理页。当进程首次运行时,会发生缺页异常,那时再分配页。请求调页机制使得系统能够运行比物理内存大的程序。
代码举例:
```c
static int do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long address, int write_access, pte_t *pte) {
struct page *new_page;
pte_t entry;
if (!vma->vm_ops || !vma->vm_ops->nopage)
return do_anonymous_page(mm, vma, address, write_access);
new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, write_access);
entry = mk_pte(new_page, vma->vm_page_prot);
if (write_access) {
entry = pte_mkwrite(pte);
} else {
entry = pte_wrprotect(pte);
}
set_pte(page_table, entry);
update_mm_ucache(vma, address, entry);
return 2;
}
```
2.2 写时复制(Copy On Writing)
写时复制是指当父进程使用 fork() 系统调用创建子进程时,系统并不立即给新进程的用户空间分配物理内存,而是通过页表映射使子进程共享父进程的内存页。但是父、子进程的页表中对应用户空间的有内存映射的页表项都被置为只读标志。当父、子进程中任何一方要写用户空间的内存页时,会触发缺页异常,系统会重新分配一页,并将其映射到进程的虚拟地址空间中。
虚拟内存技术是 Linux 内核中一个非常重要的机制,它使得系统能够运行比物理内存大的程序,同时也提高了系统的可用性和性能。