# 第09章：虚拟内存

## [视频解说](https://www.bilibili.com/video/BV1RK4y1R7Kf?p=9)

## 导读

**面试官：请解释一下什么是虚拟内存？**&#x6709;些面试官喜欢在面试的时候考察一下，或多或少能够反映出候选人的计算机基础素养，实际上内存管理（包含虚拟内存）的议题非常复杂，不是三言两语能讲清楚的，但至少你要做到心中有数，有宏观的整体把握，不至于一问三不知。

推荐你认真阅读一下Ulrich Drepper撰写的长达114页的经典论文：What Every Programmer Should Know About Memory，如果你实在没有耐心看完它，或者想了解其中的重点内容，那么也可以通过观看我自己录制的小视频来了解其中的重点内容：

[每个程序员都应该知道的内存知识 (第3部分：虚拟内存)](https://www.bilibili.com/video/BV1Xy4y1b7SK?p=3)

![](/files/-MZ6fcyQWQ-T6i2-L9N6)

虚拟内存属于 **操作系统 + 硬件** 范畴，首先，并非所有系统都使用虚拟内存，简单的（或内存受限的）系统就有可能使用单一物理内存地址空间。

![](/files/-MXq3rbvp2kJiuMlrirP)

[**物理内存有什么问题？**](https://www.bilibili.com/video/BV1XB4y1A7vm?p=5)    1. 内存空间不够  2. 产生内存碎片  3. 没有内存保护   &#x20;

（虚拟内存闪亮登场，本质就是增加一个中间层，计算机科学的任何问题都可以通过增加间接层解决！）

**虚拟内存有什么优点？**    &#x31;**.** 可以使用磁盘交换空间  2. 虚拟地址到物理地址映射灵活  3. 进程地址空间隔离

![](/files/-MXq76Vvpc0JV_J76GyC)

**相关的一些基本概念：**

虚拟地址到物理地址的转换涉及哪些硬件/软件/过程？ （MMU & TLB & Page Fault & Lazy allocation）

Lazy allocation：当程序向操作系统申请动态内存时，系统会调用相应的函数分配内存，但是这种分配并不是实时的，内核会去修改页表 Page Table，但是只有当用户真的开始使用这块内存时，才会分配物理页面（通过Page Fault 来触发）。

**Linux Kernel Space** (kmalloc, vmalloc) **& User Space** (malloc)

动态内存管理是很重要的功能，内存一直都是很宝贵的资源，一个好的内存管理策略可以极大地提升系统性能，就用户空间的动态内存管理而言，主要的实现有：ptmalloc，tcmalloc，jemalloc ...

&#x20;`GLIBC malloc` 内部通过 [`brk`](http://man7.org/linux/man-pages/man2/sbrk.2.html) 或 [`mmap`](http://man7.org/linux/man-pages/man2/mmap.2.html) 系统调用向内核申请堆内存&#x20;

\==> [glibc源码一瞥](https://elixir.bootlin.com/glibc/latest/source/malloc/malloc.c) （相关的补充参考资料： [Understanding glibc malloc](https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/)）

目前glibc的实现是ptmalloc2，它使用 chunk 作为内存管理的基本单元（Allocated chunk，Free chunk，Top chunk，Last Remainder chunk），采用边界标记法，用户 free 掉的内存并不是都会马上归还给系统，ptmalloc 会统一管理空闲的 chunk，当用户进行下一次分配请求时，ptmalloc 会首先试图在空闲的 chunk 中挑选一块给用户，这样就避免了频繁的系统调用，降低了内存分配的开销，ptmalloc 将相似大小的 chunk 用链表链接起来，这样的一个链表被称为一个 bin，ptmalloc 按照大小维护了多个类型的bin（fast bin，small bin，large bin，unsorted bin，除了fast bin是单向链表之外，其他的都是双向链表）... 另外我们还可以通过mallopt()来改变相关的内存分配行为的参数。&#x20;

**\*\*\* 案例参考（遇到的问题 & 解决的方法）**：[阿里（华庭=庄明强）：Glibc内存管理ptmalloc源代码分析](https://paper.seebug.org/papers/Archive/refs/heap/glibc%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86ptmalloc%E6%BA%90%E4%BB%A3%E7%A0%81%E5%88%86%E6%9E%90.pdf)

## 学习方式

[CMU教授的视频教程 - Lecture17：虚拟内存概念](https://www.bilibili.com/video/BV1a54y1k7YE?p=21)

[CMU教授的视频教程 - Lecture18：虚拟内存系统](https://www.bilibili.com/video/BV1a54y1k7YE?p=22)

[CMU教授的视频教程 - Lecture19：动态内存分配（基础）](https://www.bilibili.com/video/BV1a54y1k7YE?p=23)

[CMU教授的视频教程 - Lecture20：动态内存分配（进阶）](https://www.bilibili.com/video/BV1a54y1k7YE?p=24)

## 实验解读

自己动手写一个内存分配器（Memory Allocator）== 绝非易事！

![](/files/-MbO_MMeVutniCZDdD3R)

[CMU助教的视频：Malloc Lab](https://www.bilibili.com/video/BV1a54y1k7YE?p=25) （其他的补充教程： [Malloc tutorial](https://danluu.com/malloc-tutorial/)）

![](/files/-MbOmvhfRF_Sd7hgmW1S)

[CMU助教的视频：Debugging Malloc Lab](https://www.bilibili.com/video/BV1a54y1k7YE?p=26) （补充：[如何以聪明的方式提问（Eric Steven Raymond）](http://www.catb.org/~esr/faqs/smart-questions.html)）

![](/files/-MbP0Ax2G2BDVW6a24BT)

## 延伸阅读

* [Linux专题介绍：内存管理](https://www.bilibili.com/video/BV1XB4y1A7vm/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://fengmuzi2003.gitbook.io/csapp3e/dixzhang-xu-ni-nei-cun.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
