程序需要装载到内存才可以运行,每个进程都有自己的地址空间,一个进程执行时不能访问另一个进程的地址空间。
内存里可能同时装载进入多个进程。
进程地址空间
分为内核地址空间和用户地址空间,其中用户地址空间又分为:
以x86体系结构为例
栈
↓
↑
堆
数据段
代码段
进程中的地址是逻辑地址,而不是最终的物理地址,因此我们需要进行地址转换。
通常来说 用户程序经过编译、汇编形成目标代码,目标代码通常采用相对地址的形势,其首地址为0,其余地址都相对首地址而编址
因此逻辑地址不能直接在内存中读取信息,而物理地址是绝对地址,可以直接寻址
为了保证CPU执行指令时可正确访问内存单元,需要将用户程序中的逻辑地址转换为运行时可由机器直接寻址的物理地址
由内存管理单元(MMU: Memory Management Unit)完成逻辑地址到物理地址的转换
内存分配算法包括:
first fit next fit best fit等等 会有空闲区表和已分配区表
Linux底层采用的内存管理方式,伙伴系统
算法:
- 首先把整个可用空间看作一块:2^u
-
假设进程申请的空间大小为s,若满足
2^(u-1) < s <= 2^u 则分配整个块
否则将块划分为两个大小相等的伙伴,大小为2^(u-1)
-
一直划分下去直到产生大于或者等于s的最小块
CPU取到逻辑地址,划分为页号和页内地址;用页号查页表,得到页框号,再与页内偏移拼接成为物理地址 内碎片
覆盖技术overlaying
按照其自身的逻辑结构,将那些不会同时执行的程序段共享同一块内存区域
程序员声明覆盖结构,操作系统完成自动覆盖
大家不同时占用一个区域
谁执行 谁占用
交换技术(swapping)
内存空间紧张时,系统将内存中某些进程暂时移用到外存,把外存中某些进程换进内存
交换区:直接使用底层的磁盘读写操作对齐高效访问 一般系统会指定一块特殊的磁盘区域作为交换空间,包含连续的刺刀,操作系统可以使用底层的磁盘读写操作对其高效访问;
只要不用就换出;内存空间不够或者有不够的危险时换出;不应换出处于等待I/O状态的进程