动态内存管理 (1)

动态内存管理 (1)

2025 南京大学《操作系统原理》
动态内存管理 (1)

malloc() 和 free()

I call it my billion-dollar mistake. It was the invention of the null reference in 1965. (Tony Hoare)

编程语言抽象不足

  • malloc/free 也有类似的问题
    • Use after free
    • Double free
    • Memory leak
  • “最小完备性原则” 和 “机制策略分离” 的反面教材
    • “每一个 malloc 在任何可能路径上都必有一次配对的 free,且之后不再使用”
    • 在复杂系统里太难保证了
2025 南京大学《操作系统原理》
动态内存管理 (1)

malloc() 和 free()

使用的系统调用:mmap (历史:sbrk)

  • 大段内存,要多少有多少
    • 用 MAP_ANONYMOUS 申请
    • 超过物理内存上限都行 (Demo)

反而,操作系统不支持分配一小段内存

  • 这是应用程序自己的事
    • 应用程序可以每次向操作系统 “多要一点” 内存
    • 自己在内存上实现一个数据结构
2025 南京大学《操作系统原理》
动态内存管理 (1)

实现 malloc(nn)

如果 nn 足够大

  • 直接用 mmap 分配内存

如果 nn 不够大

  • 从一个 mmap 得到的内存池中分配
    • 我们有一个大区间 [L,R)[L, R)
    • 维护其中不相交的小区间集合
      • 啊!太好了!这是个数据结构问题……
      • Interval tree 可以实现 O(logn)O(\log n) 的分配/回收
2025 南京大学《操作系统原理》
动态内存管理 (1)

你们对 “现实” 的恐怖一无所知

早在 1995 年:这才叫 research

Understanding real program behavior still remains the most important first step in formulating a theory of memory management. Without doing that, we cannot hope to develop the science of memory management; we can only fumble around doing ad hoc engineering, in the too-often-used pejorative sense of the word. At this point, the needs of good science and of good engineering in this area are the same—a deeper qualitative understanding. We must try to discern what is relevant and characterize it; this is necessary before formal techniques can be applied usefully.

  • 停止无意义的 “科研实践”,去做真正有价值的事情
2025 南京大学《操作系统原理》
动态内存管理 (1)

实现高效的 malloc/free

Premature optimization is the root of all evil.

——D. E. Knuth

重要的事情说三遍:

  • 脱离 workload 做优化就是耍流氓
    • 在开始考虑性能之前,理解你需要考虑什么样的性能

然后,去哪里找 workload?

2025 南京大学《操作系统原理》
动态内存管理 (1)

理论 v.s. 实践

在实际系统中,我们通常不考虑 adversarial worst case

  • 现实中的应用是 “正常” 的,不是 “恶意” 的

malloc() 的观察

  • 大对象分配后应,读写数量应当远大于它的大小
    • 否则就是 performance bug
    • 申请 16MB 内存,扫了一遍就释放了😂
      • 这不是 bug,难道还是 feature 吗?
  • 推论:越小的对象创建/分配越频繁
2025 南京大学《操作系统原理》
动态内存管理 (1)

malloc() 的观察

我们需要管理的对象

  • 小对象:字符串、临时对象等;生存周期可长可短
  • 中对象:容器、复杂的对象;更长的生存周期
  • 大对象:巨大的容器、分配器;很长的生存周期

结论

  • 我们几乎只要管好小对象就好了 (当然,仅针对 oslabs)
  • 由于所有分配都会在所有处理器上发生
    • 小对象分配/回收的 scalability 是主要瓶颈
    • 使用链表/区间树 (first fit) 可不是个好想法
2025 南京大学《操作系统原理》
动态内存管理 (1)

malloc, Fast and Slow

人类也是这样的系统

  • Thinking, Fast and Slow by Daniel Kahneman

设置两套系统

  • Fast path (System I) ← AI 已经开始超越 System I 人类
    • 性能极好、覆盖大部分情况
    • 但有小概率会失败 (fall back to slow path)
  • Slow path (System II) ← 人类也已经失守了
    • 不在乎那么快
    • 但把困难的事情做好
  • 计算机系统里有很多这样的例子 (比如 cache)
2025 南京大学《操作系统原理》
动态内存管理 (1)

人类的智慧:空间换简洁

center

分配: Segregated List (Slab)

  • 每个 slab 里的每个对象都一样大
    • 每个线程拥有每个对象大小的 slab
    • fast path → 立即在线程本地分配完成
    • slow path → mmap()
2025 南京大学《操作系统原理》