一、内部存储管理

存储器是计算机操作系统的重要组成部分,用于存储包括程序和数据在内的各种信息。

1、程序的链接和装入

 在多到程序环境中,要使程序运行,首先必须为他创建进程,而创建进程就必须先将程序和数据装入内存。能装入内存中的程序才称为可执行程序,由用户编写的程序,要经过以下步骤,才能转变为可执行程序:首先由编译程序把用户程序编译成若干个目标模块,然后由链接程序将所有目标模块和他们需要的库函数链接在一起,形成一个完成的可装入模块。可装入模块可以通过装入程序装入内存中运行。

2.逻辑地址、物理地址和虚拟地址

逻辑地址:用户程序经过编译、链接后得到的可装入程序(可装入程序:是一个二进制文件)。由于无法预知程序装入内存时的具体位置,因此不可能在程序中直接使用内存地址,只能规定程序的起始地址都是0,而程序指令和数据的地址都是根据相对0起始地址进行计算的。所以装入程序中的地址都是逻辑地址,一个程序的逻辑地址集合即为逻辑地址空间

逻辑地址空间:如何确定逻辑地址空间呢?我们知道操作系统分为32位和64位的。这样的区分就在于逻辑地址长度的不同。32位操作系统表示逻辑地址长度为32bit的二进制。64位操作系统表示逻辑地址长度是64bit位的二进制。例如:32位操作系统,逻辑地址就可以从0000 0000 0000 0000 0000 0000 0000 0000 到1111 1111 1111 1111 1111 1111 1111 1111 那么一共多少个呢?一共2^32(即4G)个。所以我们常说32位操作系统逻辑地址空间为4G的字节。此时每个字节使用了32位来表示。

物理地址:内存中实际存在的存储单元的地址。整个内存空间又叫做物理地址空间

虚拟地址:是在使用的虚拟存储技术时,虚拟空间中的地址。虚拟内存的空间又叫做虚拟地址空间。

3.分区式存储管理(已经弃用)

分区式存储:对内存采用连续分配方式,即根据用户程序的需求为之在内存中分配一段连续的存储空间。包括两种方式:固定分区和动态分区

1)固定分区:将内存分为系统区和用户区。用户区再被分成大小相同(或者大小不同但是固定)的区块。为此,系统建立了一张分区分配表,如下:

分区号

起始地址

长度

占用标志

1

8K

8K

0

2

16K

16K

Job1

3

32K

16K

0

4

48K

64K

0

5

64K

32K

Job2

6

96K

32K

0

固定分区存储管理的主存分配表

缺点:若用户程序太大,则不能装入内存中,若程序太小,又会造成空间的浪费

2)动态分区:用户区根据用户程序的大小进行分区,主存中分区的数目和大小随作业的执行而不断改变。为了方便主存的分配和去配,主存分配表可由两张表格组成,一张 已分配区的情况表,另一张是未分配区的情况表,如下:

分区号

起始地址

长度

标志

1

4K

6K

Job1

4

46K

6K

Job2

 

 

 

 

(a)已分配区情况表

分区号

起始地址

长度

标志

2

10K

36K

未分配

3

52K

76K

未分配

(b)未分配区情况表

可变分区存储管理的主存分配表

缺点:随着时间的推移,会导致内存中存在很多碎片

4.分页式存储管理

因为分区式存储管理是连续分配存储空间,为了能实现离散性分配内存。引入了分页式存储管理

分页式存储管理:将程序的逻辑地址和内存的物理地址都划分成等大小的区域。这个区域叫做页。然后将程序的逻辑地址离散的装入内存中,为了保证程序的运行逻辑,故而引入了页表,页表中记录了逻辑页和内存页的对应关系。 同时为了获知内存的物理块使用情况,为此系统建立了内存空间使用表。如下:

缺点:如果页面划分太大,会导致空间的浪费,形成过多的碎片;如果页面太小,虽然减少了页面碎片,但是会使页表增大,进而占用更多的空间。

5.分段式存储管理

以前的存储方式都是一维线性。导致代码程序不能实现模块化调用。然而事实上,程序大多采用分段结构,一个程序可以由主程序段、子程序段、数据段和工作区段等组成,每个段有各自的名字和长度、实现不同的功能。若能以段为单位为程序离散分配内存,将满足用户更多需要。为了实现这种功能,系统建立了段表。如下:

 

缺点:可以看出来,分段式存储的确实现了按段分配内存,同时实现了空间分配的离散性,但是同时具有了动态分区存储的特性,会随着时间的推移,空间的碎片会增多。

6.段页式存储管理(普遍使用中)

为了能够综合分页式和分段式存储的优点,所以引进了段页式的存储管理。

将程序按照划分为多个段,然后将段再按照分页式存储管理的方式进行存储。

7.虚拟存储管理

以上讲了那么多种的存储方式,但他们都是一次性装入内存,若程序很大,其要求的内存空间超过当前系统的能够提供的内存空间,将会导致程序装入内存失败,从而导致程序无法运行(简称一次性)。同时,程序装入内存后,就会一直驻留在内存中,知道进程结束(简称:驻留性),为了解决这两个问题,所以引进了虚拟存储技术。

虚拟存储技术主要依附两点:1.将程序部分装入内存,当运行所需要的程序不在内存中时,可以通过调入功能将其装入;2.当内存空间已满,将内存中暂时不执行的进程(或者程序)暂时从内存中调出,然后将需要运行的程序装入内存个中。

为了实现上面两点,系统需具备的条件:

1.)缺页中断机制。若运行所需程序不在内存中,操作系统将会根据缺页中断引号执行响应的缺页中断处理程序,根据页表将对应的页从外存(磁盘)中装入内存。

2)外存交换区。为了从逻辑上扩大内存空间,一般将磁盘空间分为文件区和交换区,交换区中存放的是在内存和磁盘间交换的程序和数据。

3)换入、换出机制。什么页面该换入,什么页面该换出,所以就必须通过页面置换算法来决定。

8.缓存机制

 

二、Mem总结

当内存不足的时候,内核的页面扫描器(page scanner)就开始查找应用不再使用的内存页(不使用的内存页一般都会写回磁盘),以便其他应用和进程可以使用这些内存。如果页面扫扫描器找不到可供其他应用使用的内存页,也没有额外可用的物理内存(一般情况下,系统都会设置一个下限,当当达到这个下限就会调用SWAP),他就会将最近最少使用的内存页置换到磁盘的SWAP空间上。可用内存越少,内存扫描的次数越多。
 kswapd daemon 用来检查 pages_high 和 pages_low,如果可用内存少于 pages_low,kswapd 就开始扫描并试图释放 32个页面,

并且重复扫描释放的过程直到可用内存大于 pages_high 为止。扫描的时候检查3件事:1)如果页面没有修改,把页放到可用内存列表里;

2)如果页面被文件系统修改,把页面内容写到磁盘上;3)如果页面被修改 了,但不是被文件系统修改的,把页面写到交换空间。

•    pdflush daemon 用来同步文件相关的内存页面,把内存页面及时同步到硬盘上。比如打开一个文件,文件被导入到内存里,
对文件做了修改后并保存后,内核并不马上保存文件到硬 盘,由 pdflush 决定什么时候把相应页面写入硬盘,这由一个内核参数 
vm.dirty_background_ratio 来控制,比如下面的参数显示脏页面(dirty pages)达到所有内存页面10%的时候开始写入硬盘。

三、Mem 评估指标

1、可用内存
vmstat 中的free 或者 free中的free

2、实际使用内存
free中的used,包含了分配的cache和buffer, 这部分cache和buffer有可能并没有使用;

3、swap区域使用大小
(1)如果vmstat swpd的值不为0,或者比较大,比如超过了100m,只要si、so的值长期为0,系统性能还是正常

4、swap in / out

5、cache

6、buffer

5.6 是怎么被区分出来的?分配和使用规则是?cache和buffer到底什么区别?

四、分析实例

 

上面是一个频繁读写交换区的例子,可以观察到以下几点: 
•    物理可用内存 free 基本没什么显著变化,swapd 逐步增加,说明最小可用的内存始
终保持在 256MB X 10% = 2.56MB 左右,当脏页达到10%的时候(vm.dirty_background_ratio = 10)就开始大量使用 swap; 
•    buff 稳步减少说明系统知道内存不够了,kwapd 正在从 buff 那里借用部分内存; 
•    kswapd 持续把脏页面写到 swap 交换区(so),并且从 swapd 逐渐增加看出确实如此。
根据上面讲的 kswapd 扫描时检查的三件事,如果页面被修改了,但不是被文件系统修改的,把页面写到 swap,
所以这里 swapd 持续增加。 
io中的bi和bo分别是:每秒钟从块设备读入的块数量和每秒钟发送到块设备的块数量。
 
posted on 2017-07-17 15:33  进_进  阅读(888)  评论(0)    收藏  举报