“拆解” 应用程序

“拆解” 应用程序

2024 南京大学《操作系统:设计与实现》
“拆解” 应用程序

“拆解应用程序” 的需求 (1)

实现运行库和应用代码分离

  • 应用之间的库共享
    • 每个程序都需要 glibc
    • 但系统里只需要一个副本就可以了
      • 是的,我们可以用 ldd 命令查看
  • 大型项目的分解
    • 改一行代码不用重新链接 2GB 的文件
    • libjvm.so, libart.so, ...
      • NEMU: “把 CPU 插上主板”
2024 南京大学《操作系统:设计与实现》
“拆解” 应用程序

“拆解应用程序” 的需求 (2)

库的依赖也是一种代码克隆

如果 Linux 应用世界是静态链接的……

  • libc 紧急发布安全补丁 → 重新链接所有应用 😂
  • Semantic Versioning
    • “Compatible” 是个有些微妙的定义
    • “Dependency hell”
2024 南京大学《操作系统:设计与实现》
“拆解” 应用程序

实现应用程序的拆解

方案 1: libc.o

  • 在加载时完成重定位
    • 加载 = 静态链接
    • 省了磁盘空间,但没省内存
    • 致命缺点:时间 (链接需要解析很多不会用到的符号)

方案 2: libc.so (shared object)

  • 编译器生成位置无关代码
    • 加载 = mmap
    • 但函数调用时需要额外一次查表
  • 好处:多个进程映射同一个 libc.so,内存中只需要一个副本
2024 南京大学《操作系统:设计与实现》
“拆解” 应用程序

验证 “只有一个副本”

如何实现?

  • 构造一个非常大的 libbloat.so
    • 我们的例子:100M of nop (0x90)
  • 创建 1,000 个进程动态链接 libbloat.so 的进程
  • 观察系统的内存占用情况
    • 100MB or 100GB?
    • 如果是后者,直播会立即翻车;但 out-of-memory killer 会杀死 oom_score 最高的进程
      • Prototypes are easy. Production is hard. (Elon Musk)
2024 南京大学《操作系统:设计与实现》
“拆解” 应用程序

推论:初探进程地址空间的实现

地址空间表面是 “若干连续的内存段”

  • 通过 mmap/munmap/mprotect 维护
  • 实际是分页机制维护的 “假像”

center

2024 南京大学《操作系统:设计与实现》