内存管理
挑着看把,视频本身就没有讲清楚,
1.内存层次
- CPU中, 加法器ALU直接访问寄存器, 寄存器(数量少, 空间小)如果没有要的数据就去cache里找,找到以后放到寄存器, 再由寄存器共给ALU来运算
- CPU通过总线访问内存和I/O设备(磁盘等), 当cache也没有要的数据时,就会再从内存中取数据给到cache, 再给寄存器,然后给加法器。(当内存里也没有就去找I/O设备,不断向上直至给到alu)
- 寄存器 -> cache -> 内存 -> I/0设备 (速度越来越慢,空间越来越大) 这样构成了计算机的存储体系
2.实模式
-
在程序中直接使用内存,CPU直接访问设备(显卡, 网卡, 内存条)的物理地址, 通过段寄存器(指定段的起始位置)加段内偏移量来访问地址
-
段基值, 段内偏移量
3.内存管理
- 让操作系统来管理内存, 需要内存时向操作系统申请, 操作系统会自动分配一块内存出来。
- 操作系统内核管理着内存, MMU启动以后就工作在保护模式以后, 用户看到的地址就不再是物理地址, 而是虚拟地址。 MMU单元负责物理地址和虚拟地址的相互转换。
- 操作系统上运行4个进程 PA, PB, PC, PD, 如图底所示,操作系统内核占据这物理地址的前半部分, 后面接着2个PA进程, 1个PC进程, 1个PB进程,2个PD进程, 而我们是看不到物理地址的, 我们能看到的只是MMU提供的虚拟地址
- 操作系统内核也是一个程序,MMU单元起来以后,操作系统内核,PA等在操作系统之上的看到的地址都是虚拟地址
4.保护模式
- 虚拟地址和物理地址的联系
- 逻辑地址(segment:offset)段选择子:段内偏移
- 逻辑地址经过分段转化为线性地址(虚拟地址)
- 线性地址经过分页转为物理地址
- GDT, LDT
5. 映射文件
- cat /proc/$$/maps
- 第一列是段的起始地址和段的结束地址(地址范围)
- 第二列是权限(r 代表只读, x 代表可执行, w 代表写, p代表私有的, s代表共享的)
- 第三列代表段内偏移
- 第四列是映射文件设备号(主设备号:次设备号)
- 第五列是映射文件i节点号
- 第六列是库路径 ??
- 每个进程都会这几个段: 代码段, 数据段 ,栈段 和 堆
- r-xp 代表可读可执行,应该是代码段
- r–p 代表只读,应该是只读数据段
- rw-p 是数据段
- head 是堆
- /lib/i386… .so 是动态共享库, 说明这进程执行时依赖这个动态共享库
- stack 是栈段, heap 是堆
- 如果编译时,变量的空间被分配到数据段了, 那么这个数据段的地址就确定了, 这是一个静态的地址,程序执行过程中也是不会动的
- heap和stack是程序执行的过程当中,操作系统动态分配的。
- stack (栈,先进后出)程序执行系统自动分配的。
- heap (堆,先进先出) 是在程序运行的过程中需要使用内存(malloc…)的时候, 系统才会分配内存
6. 进程的映射
MMU将虚拟地址映射到物理地址是以页(Page)为单位的,对于32位CPU通常一页为4K。例如,虚拟地址0xb700 1000 ~ 0xb700 1fff是一个页,可能被MMU映射到物理地址0x2000~0x2fff,物理内存中的一个物理页面也称为一个页框(Page Frame)。MMU把 物理内存里的页框 和 虚拟内存里的页对应起来。
最后一段参考:
虚拟地址、逻辑地址、线性地址、物理地址