9.1物理和虚拟寻址
计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组。每字节都有唯一的一个物理地址,CPU访问内存最自然的方式就是使用物理地址。我们把这种方式叫做物理寻址。



9.2地址空间
{0,1,2,...}


9.3虚拟内存作为缓存的工具



9.3.1DRAM缓存的组织结构

9.3.2页表


页表就是一个页表条目(PTE)的数组,每个PTE都由一个有效位和一个n位地址字段组成

9.3.3页命中

9.3.4缺页



如果VP4已经被修改,那么内核就会将它复制回磁盘
9.3.5分配页面

9.3.6又是局部性救了我们


9.4虚拟内存作为管理内存的工具



9.5虚拟内存作为内存保护的工具


9.6地址翻译







9.6.1结合高速缓存和虚拟内存

9.6.2利用TLB加速地址翻译
PTE的一个小的缓存,称为翻译后备缓冲器(Translation Lookaside Buffer,TLB),其中每一行保存一个由单个PTE组成的块。





9.6.3多级页表




9.6.4综合:端到端的地址翻译







9.7案例研究:Intel Core i7/Linux内存系统
9.7.1Core i7地址翻译




9.7.2Linux虚拟内存系统

1.Linux虚拟内存区域



2.Linux缺页异常处理

9.8内存映射


9.8.1再看共享对象


9.8.2再看fork函数

9.8.3再看execve函数

9.8.4使用mmap函数的用户级内存映射





9.9动态内存分配



9.9.1malloc和free函数



9.9.2为什么要使用动态内存分配
9.9.3分配器的要求和目标
要求:

目标:


9.9.4碎片


9.9.5实现问题

9.9.6隐式空闲链表


9.9.7放置已分配的块



9.9.8分割空闲块

9.9.9获取额外的堆内存

9.9.10合并空闲块



9.9.11带边界标志的合并



9.9.12综合:实现一个简单的分配器
9.9.13显式空闲链表



9.9.14分离的空闲存储
9.10垃圾收集
9.10.1垃圾收集器的基本知识

9.10.12Mark&Sweep垃圾收集器
9.11C程序中常见的与内存相关的错误
9.11.1间接引用坏指针



9.11.2读未初始化的内存

9.11.3允许栈缓存区溢出
9.11.4假设指针和它们指向的对象是相同大小的
9.11.5造成错位错误
9.11.6引用指针,而不是它所指向的对象
9.11.7误解指针运算
9.11.8引用不存在的变量
9.11.9引用空闲堆块中的数据
9.11.10引起内存泄漏
