内存管理:
在多道程序环境下,系统当中有多道程序并发的执行,也就是说会有多道程序的数据都会储存在内存当中,那么操作系统是如何区分各道程序的数据是放在什么地方的呢?
给内存的存储单元进行编址,将内存划分为多个小房间,每个小房间就是一个存储单元。如果计算机是按照字节编址,那么每个存储单元大小就是一个字节,即1B,占8位。如果按照字编址,那么一个存储单元就是1字,16位。在liinux操作系统当中内存是按字节编址的。
单位转换:
1个字节就是8位
2^10 = 1K
2^20 = 1M
2^30 = 1G
因此4G B = 4 * 2^30 B 也就是2^32字节。也就是2^32个小房间。因此需要的地址长度就是32个二进制数来标识这些个小房间。
指令的工作流程:
以x = x + 1为例
最开始是这段代码,经过编译器编译,生成一份可执行文件,这个可执行文件当中就是一系列的指令,然后CPU就需要按照指令进行执行。
首先执行指令1,根据指令1当中的类型参数,判断该指令是数据传送指令,然后根据参数在内存当中找到数据x,并将数据加载进CPU的寄存器当中。
然后执行指令2,根据指令2当中的类型参数,判断该指令是加法指令,便会让CPU寄存器当中的值也就是x与相对应的值1进行相加,并将结果写进寄存器。
最后执行指令3,根据指令3当中的类型参数,判断该指令是数据传送指令,便会将CPU寄存器当中的结果值加载进内存当中,将旧x值覆盖。
当然,指令当中所写的都是数据的逻辑地址,在CPU执行的时候都需要加上初始地址得到物理地址。
逻辑地址与物理地址转换方式:
绝对装入:我们一开始就知道内存开始地址在哪里,那么在编译的时候,在处理地址的时候就直接在可执行文件当中写入数据的物理地址。(这种方式是最早的地址装入方式,而且还不能够在不同的操作系统当中运行)
静态重定位:在编译过后得到的可执行文件当中的数据地址还是逻辑地址,但当这些可执行文件加载进内存后,数据地址便会进行重定位,也就是会为数据地址加上内存的初始值。(这种方式,需要操作系统为其分配完整连续的内存,不能够进行分割,因为不同的模块存在不同的地址上时,模块的初始地址就不一样了,那么在加载进内存时逻辑地址转换位物理地址的时候,初始地址就无法正确确定)
动态重定位:在编译过后以及加载进内存过后的地址还是逻辑地址,只有在CPU执行的时候,才会加上重定位寄存器当中的值形成物理地址。
连续分配管理:
动态分区分配当中常见的一些算法:
非连续分配管理:
基本分页管理:
将内存空间分割成多个小的分区,简称“页框”,每个页框都有一个自己的编号。可以根据编号求出,在内存当中的地址。
进程中的指令段和数据段也会被分成多个页,这些页会被存储进内存当中的页框当中。这个进程分割成的页的大小是和内存当中页框的大小是一样大的。
每个进程都会拥有自己的页表,该页表是存在进程的PCB当中的,也就是系统内存当中。
地址变换:
TLB缓存,这个速度缓存的读取速度比内存要快但要比寄存器要低。在CPU进行进程切换的时候,TLB缓存中的页表数据会被清空。
加了TLB缓存之后的地址转换:
页表项:就是页表当中一行的空间
页表中含有多个页表项
单级页表的缺点:如果页数量太多了,那么就会导致页表占用的内存过大,且必须是连续存储,内存当中很难找到那么大的连续空间。
因此我们可以为页表在建立一个页目录,这样这些页表就能够进行分组,然后放在内存当中不同的位置上了。