Memory management in OS

 

操作系统内存管理方式

Chap.1

如何将计算机上有限的物理内存分配给多个程序使用

  • 地址空间不隔离
  • 内存使用效率低
  • 程序运行的地址不确定

由此引出了中间层:虚拟地址

分段:将一段与程序所需要的内存空间大小的虚拟空间映射到某个地址空

  • 解决了第一和第三个问题

粒度更小的内存分割和映射方法:分页——将地址空间人为等分为固定大小的页

内存共享

页错误:进程需要->硬件捕获->操作系统接管进程:从磁盘中读出数据+建立页之间的映射关系

CPU->MMU:virtual address

MMU->Physical Memory:physical address

Chap.6

装载的方式:动态装入-程序运行的局部性原理

动态装入的思想:程序用到哪个模块,就将哪个模块装入内存,如果不用就暂时不装入,存放在磁盘当中

覆盖装入

在现代嵌入式的内存受限环境下,这种方法具有一定的应用价值

覆盖管理器->组织成树状的调用依赖关系

调用路径:当某个模块被调用时,整个调用路径上的模块必须都在内存中,以确保模块执行完毕后能正确返回

禁止跨树间的调用:模块归并

覆盖装入,速度较慢

页映射

替换算法的选择:FIFO、LUR等

现在操作系统的存储管理器普遍采用这种方式

从操作系统角度看可执行文件的装载

进程建立

  • 创立一独立的虚拟地址空间
    • 分配页目录等映射函数所需的相应数据结构
  • 读取可执行文件头,并且建立虚拟空间与可执行文件的映射关系
    • VMA:虚拟内存区域
  • 将CPU的指令寄存器设置成可执行文件的入口地址,启动运行

页错误

  • 查询第二步中建立的数据结构
  • 找到空页面所在的VMA
  • 计算出相应的页面在可执行文件中的偏移
  • 在物理内存中分配一相应页面
  • 将进程中该虚拟页与分配的物理页之间建立映射关系

elf的空间进一步优化:segment概念的引入

对于相同权限的段,将其合并到一起当作一个段进行映射 所有相同属性的Section被归类到一个Segment,并且映射到同一个VMA

一个进程基本上可以分为4种VMA段

  • 代码VMA,只读可执行,有映像
  • 数据VMA,可读写、==可执行==,有映像
  • 堆VMA,可读写、==可执行==,无映像,匿名向上扩展
  • 栈VMA,可读写、==不可执行==,无映像,匿名向下扩展

查看可执行文件的Section: readelf -S [file] 查看Segment:readelf -l [file]

段地址对齐

导致各个段的虚拟地址往往不是系统页面长度的整数倍

计算:

现有VMA0的起始地址为0x08048000,长度为0x709e5,VMA1与VMA0的最后一个虚拟页面共享一个物理页面,页面大小为0x1000,映射两遍,则VMA1地址为________

进程栈的初始化

在Ubuntu17.04下,初始化之后的栈空间发生了变化

ELF和PE的装载

ELF

fork()->execve()->sys_execve()->do_execve()->load_elf_binary()

PE

计算

1