进程的地址空间管理

进程的地址空间管理

2025 南京大学《操作系统原理》
进程的地址空间管理

往后想一想

进程的初始状态

  • 只有ELF 文件里声明的内存和一些操作系统分配的内存
    • 任何其他指针的访问都是非法的
    • 如果我们从输入读一个 size,然后 malloc(size)
      • 内存从拿来呢?

一定有一个系统调用可以改变进程的地址空间

  • 你会怎么设计?
2025 南京大学《操作系统原理》
进程的地址空间管理

Memory Map 系统调用

在状态机状态上增加/删除/修改一段可访问的内存

  • MAP_ANONYMOUS: 匿名 (申请) 内存
  • fd: 把文件 “搬到” 进程地址空间中 (例子:加载器)
  • 更多的行为请参考手册 (复杂性暴增)
// 映射
void *mmap(void *addr, size_t length, int prot, int flags,
           int fd, off_t offset);
int munmap(void *addr, size_t length);

// 修改映射权限
int mprotect(void *addr, size_t length, int prot);
  • 我们可以用 pmap 命令查看进程的地址空间
    • (它是怎么实现的?)
2025 南京大学《操作系统原理》
进程的地址空间管理

使用 mmap

Example 1: 申请大量内存空间

  • 瞬间完成内存分配
    • mmap/munmap 为 malloc/free 提供了机制
    • libc 的大 malloc 会直接调用一次 mmap 实现
  • 不妨 strace/gdb 看一下

Example 2: Everything is a file

  • 映射大文件、只访问其中的一小部分
with open('/dev/sda', 'rb') as fp:
    mm = mmap.mmap(fp.fileno(),
                   prot=mmap.PROT_READ, length=128 << 30)
    hexdump.hexdump(mm[:512])
2025 南京大学《操作系统原理》