在进入正题前先来谈谈操作系统内存管理机制的发展历程,了解这些有利于我们更好的理解目前操作系统的内存管理机制。

早期的内存分配机制

在 早期的计算机中,要运行一个程序,会把这些程序全都装入内存,程序都是直接运行在内存上的,也就是说程序中访问的内存地址都是实际的物理内存地址。当计算 机同时运行多个程序时,必须保证这些程序用到的内存总量要小于计算机实际物理内存的大小。那当程序同时运行多个程序时,操作系统是如何为这些程序分配内存 的呢?下面通过实例来说明当时的内存分配方法:

某台计算机总的内存大小是 128M ,现在同时运行两个程序 A 和 B , A 需占用内存 10M , B 需占用内存 110 。计算机在给程序分配内存时会采取这样的方法:先将内存中的前 10M 分配给程序 A ,接着再从内存中剩余的 118M 中划分出 110M 分配给程序 B 。这种分配方法可以保证程序 A 和程序 B 都能运行,但是这种简单的内存分配策略问题很多。

图一

早期的内存分配方法

问题
1
:进程地址空间不隔离。由于程序都是直接访问物理内存,所以恶意程序可以随意修改别的进程的内存数据,以达到破坏的目的。有些非恶意的,但是有
bug
的程序也可能不小心修改了其它程序的内存数据,就会导致其它程序的运行出现异常。这种情况对用户来说是无法容忍的,因为用户希望使用计算机的时候,其中一个任务失败了,至少不能影响其它的任务。

问题
2
:内存使用效率低。在
A

B
都运行的情况下,如果用户又运行了程序
C
,而程序
C
需要
20M
大小的内存才能运行,而此时系统只剩下
8M
的空间可供使用,所以此时系统必须在已运行的程序中选择一个将该程序的数据暂时拷贝到硬盘上,释放出部分空间来供程序
C
使用,然后再将程序
C
的数据全部装入内存中运行。可以想象得到,在这个过程中,有大量的数据在装入装出,导致效率十分低下。

问题
3
:程序运行的地址不确定。当内存中的剩余空间可以满足程序
C
的要求后,操作系统会在剩余空间中随机分配一段连续的
20M
大小的空间给程序
C
使用,因为是随机分配的,所以程序运行的地址是不确定的。


分段

为 了解决上述问题,人们想到了一种变通的方法,就是增加一个中间层,利用一种间接的地址访问方法访问物理内存。按照这种方法,程序中访问的内存地址不再是实
际的物理内存地址,而是一个虚拟地址,然后由操作系统将这个虚拟地址映射到适当的物理内存地址上。这样,只要操作系统处理好虚拟地址到物理内存地址的映 射,就可以保证不同的程序最终访问的内存地址位于不同的区域,彼此没有重叠,就可以达到内存地址空间隔离的效果。

当创建一个进程时,操作系统会为该进程分配一个
4GB
大小的虚拟
进程地址空间。之所以是
4GB
,是因为在
32
位的操作系统中,一个指针长度是
4
字节,而
4
字节指针的寻址能力是从
0x00000000~0xFFFFFFFF
,最大值
0xFFFFFFFF
表示的即为
4GB
大小的容量。与虚拟地址空间相对的,还有一个物理地址空间,这个地址空间对应的是真实的物理内存。如果你的计算机上安装了
512M
大小的内存,那么这个物理地址空间表示的范围是
0x00000000~0x1FFFFFFF
。当操作系统做虚拟地址到物理地址映射时,只能映射到这一范围,操作系统也只会映射到这一范围。当进程创建时,每个进程都会有一个自己的
4GB
虚拟地址空间。要注意的是这个
4GB
的地址空间是“虚拟”的,并不是真实存在的,而且每个进程只能访问自己虚拟地址空间中的数据,无法访问别的进程中的数据,通过这种方法实现了进程间的地址隔离。那是不是这
4GB
的虚拟地址空间应用程序可以随意使用呢?很遗憾,在
Windows
系统下,这个虚拟地址空间被分成了
4
部分:
NULL
指针区、用户区、
64KB
禁入区、内核区。应用程序能使用的只是用户区而已,大约
2GB
左右
(
最大可以调整到
3GB)
。内核区为
2GB
,内核区保存的是系统线程调度、内存管理、设备驱动等数据,这部分数据供所有的进程共享,但应用程序是不能直接访问的。

人 们之所以要创建一个虚拟地址空间,目的是为了解决进程地址空间隔离的问题。但程序要想执行,必须运行在真实的内存上,所以,必须在虚拟地址与物理地址间建
立一种映射关系。这样,通过映射机制,当程序访问虚拟地址空间上的某个地址值时,就相当于访问了物理地址空间中的另一个值。人们想到了一种分段

(Sagmentation)
的方法,它的思想是在虚拟地址空间和物理地址空间之间做一一映射。比如说虚拟地址空间中某个
10M
大小的空间映射到物理地址空间中某个
10M
大小的空间。这种思想理解起来并不难,操作系统保证不同进程的地址空间被映射到物理地址空间中不同的区域上,这样每个进程最终访问到的

物理地址空间都是彼此分开的。通过这种方式,就实现了进程间的地址隔离。还是以实例说明,假设有两个进程
A

B
,进程
A
所需内存大小为
10M
,其虚拟地址空间分布在
0x00000000

0x00A00000
,进程
B
所需内存为
100M
,其虚拟地址空间分布为
0x00000000

0x06400000
。那么按照分段的映射方法,进程
A
在物理内存上映射区域为
0x00100000

0x00B00000
,,进程
B
在物理内存上映射区域为
0x00C00000

0x07000000
。于是进程
A
和进程
B
分别被映射到了不同的内存区间,彼此互不重叠,实现了地址隔离。从应用程序的角度看来,进程
A
的地址空间就是分布在
0x00000000

0x00A00000
,在做开发时,开发人员只需访问这段区间上的地址即可。应用程序并不关心进程
A
究竟被映射到物理内存的那块区域上了,所以程序的运行地址也就是相当于说是确定的了。

图二显示的是分段方式

的内存映射方法。

图二

分段方式的内存映射方法


种分段的映射方法虽然解决了上述中的问题一和问题三,但并没能解决问题二,即内存的使用效率问题。在分段的映射方法中,每次换入换出内存的都是整个程序,
这样会造成大量的磁盘访问操作,导致效率低下。所以这种映射方法还是稍显粗糙,粒度比较大。实际上,程序的运行有局部性特点,在某个时间段内,程序只是访
问程序的一小部分数据,也就是说,程序的大部分数据在一个时间段内都不会被用到。基于这种情况,人们想到了粒度更小的内存分割和映射方法,这种方法就是分页

(Paging)


分页

分页的基本方法是,将地址空间分成许多的页。每页的大小由
CPU
决定,然后由操作系统选择页的大小。目前
Inter
系列的
CPU
支持
4KB

4MB
的页大小,而
PC
上目前都选择使用
4KB
。按这种选择,
4GB
虚拟地址空间共可以分成
1048576
个页,
512M
的物理内存可以分为
131072
个页。显然虚拟空间的页数要比物理空间的页数多得多。

在 分段的方法中,每次程序运行时总是把程序全部装入内存,而分页的方法则有所不同。分页的思想是程序运行时用到哪页就为哪页分配内存,没用到的页暂时保留在
硬盘上。当用到这些页时再在物理地址空间中为这些页分配内存,然后建立虚拟地址空间中的页和刚分配的物理内存页间的映射。

下面通过介绍一个可执行文件的装载过程来说明分页机制的实现方法。一个可执行文件
(PE
文件
)
其实就是一些编译链接好的数据和指令的集合,它也会被分成很多页,在
PE
文件执行的过程中,它往内存中装载的单位就是页。当一个
PE
文件被执行时,操作系统会先为该程序创建一个
4GB
的进程虚拟地址空间。前面介绍过,虚拟地址空间只是一个中间层而已,它的功能是利用一种映射机制将虚拟地址空间映射到物理地址空间,所以,创建
4GB
虚拟地址空间其实并不是要真的创建空间,只是要创建那种映射机制所需要的数据结构而已,这种数据结构就是页目和页表。

当创建完虚拟地址空间所需要的数据结构后,进程开始读取
PE
文件的第一页。在
PE
文件的第一页包含了
PE
文件头和段表等信息,进程根据文件头和段表等信息,将
PE
文件中所有的段一一映射到虚拟地址空间中相应的页
(PE
文件中的段的长度都是页长的整数倍
)
。这时
PE
文件的真正指令和数据还没有被装入内存中,操作系统只是根据
PE
文件的头部等信息建立了
PE
文件和进程虚拟地址空间中页的映射关系而已。当
CPU
要访问程序中用到的某个虚拟地址时,当
CPU
发现该地址并没有相相关联的物理地址时,
CPU
认为该虚拟地址所在的页面是个空页面,
CPU
会认为这是个页错误
(Page Fault)

CPU
也就知道了操作系统还未给该
PE
页面分配内存,
CPU
会将控制权交还给操作系统。操作系统于是为该
PE
页面在物理空间中分配一个页面,然后再将这个物理页面与虚拟空间中的虚拟页面映射起来,然后将控制权再还给进程,进程从刚才发生页错误的位置重新开始执行。由于此时已为
PE
文件的那个页面分配了内存,所以就不会发生页错误了。随着程序的执行,页错误会不断地产生,操作系统也会为进程分配相应的物理页面来满足进程执行的需求。

分页方法的核心思想就是当可执行文件执行到第
x
页时,就为第
x
页分配一个内存页
y
,然后再将这个内存页添加到进程虚拟地址空间的映射表中
,
这个映射表就相当于一个
y=f(x)
函数。应用程序通过这个映射表就可以访问到
x
页关联的
y
页了。

总结:

32

位的CPU
的寻址空间是4G
,
所以虚拟内存的最大值为4G
,
而windows
操作系统把这4G
分成2
部分,
即2G
的用户空间和2G
的系统空间,
系统空间是各个进程所共享的,
他存放的是操作系统及一些内核对象等,
而用户空间是分配给各个进程使用的,
用户空间包括用:
程序代码和数据,
堆,
共享库,
栈。

系统虚拟内存的理解 转载自http://blog.csdn.net/do2jiang/article/details/4690967的更多相关文章

  1. 联想笔记本 thinkpad BIOS 超级密码 Supervisor Password 清除 破解 亲测有效 转载地址https://blog.csdn.net/ot512csdn/article/details/72571674

    联想笔记本 thinkpad BIOS 超级密码 Supervisor Password 清除 破解 亲测有效 转载地址https://blog.csdn.net/ot512csdn/article/ ...

  2. R语言中的正则表达式(转载:http://blog.csdn.net/duqi_yc/article/details/9817243)

    转载:http://blog.csdn.net/duqi_yc/article/details/9817243 目录 Table of Contents 1 正则表达式简介 2 字符数统计和字符翻译 ...

  3. 数组中&a与&a[0]的区别 转载自http://blog.csdn.net/FX677588/article/details/74857473

    在探讨这个问题之前,我们首先来看一道笔试题,如下: [摘自牛客网]下列代码的结果是:(正确答案是 C) main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)( ...

  4. Win32消息循环机制等【转载】http://blog.csdn.net/u013777351/article/details/49522219

    Dos的过程驱动与Windows的事件驱动 在讲本程序的消息循环之前,我想先谈一下Dos与Windows驱动机制的区别: DOS程序主要使用顺序的,过程驱动的程序设计方法.顺序的,过程驱动的程序有一个 ...

  5. Oracle RAC 全局等待事件 gc current block busy 和 gc cr multi block request 说明--转载(http://blog.csdn.net/tianlesoftware/article/details/7777511)

    一.RAC 全局等待事件说明 在RAC环境中,和全局调整缓存相关的最常见的等待事件是global cache cr request,global cache busy和equeue. 当一个进程访问需 ...

  6. 转载:https://blog.csdn.net/qq_22706515/article/details/52595027

    https://blog.csdn.net/qq_22706515/article/details/52595027 包含直播,即时通讯. 大平台都有免费版或基础版,对于需求不大的情况比较适合.

  7. 手机网络抓包 转载记录http://blog.csdn.net/skylin19840101/article/details/43485911

    Fiddler不但能截获各种浏览器发出的HTTP请求, 也可以截获各种智能手机发出的HTTP/HTTPS请求.Fiddler能捕获IOS设备发出的请求,比如IPhone, IPad, MacBook. ...

  8. matlab 降维工具 转载【https://blog.csdn.net/tarim/article/details/51253536】

    降维工具箱drtool   这个工具箱的主页如下,现在的最新版本是2013.3.21更新,版本v0.8.1b http://homepage.tudelft.nl/19j49/Matlab_Toolb ...

  9. WPF之Binding深入探讨 转载:http://blog.csdn.net/fwj380891124/article/details/8107646

    1,Data Binding在WPF中的地位 程序的本质是数据+算法.数据会在存储.逻辑和界面三层之间流通,所以站在数据的角度上来看,这三层都很重要.但算法在3层中的分布是不均匀的,对于一个3层结构的 ...

随机推荐

  1. 直接用bcdedit创建bootmgr数据库和修复启动菜单

    直接用bcdedit创建bootmgr数据库和修复启动菜单 使用下面方法之前需要bcdedit和bootsect两条命令,这两条命令可以到vista或者windows 7安装光盘上获得.bootsec ...

  2. vue中文本域限制字数的方法

    用watch方法,来限制字数 <template> <div class="box"> <textarea v-model="title&q ...

  3. NOIP模拟赛 无线通讯网

    [题目描述] 国防部计划用无线网络连接若干个边防哨所.2种不同的通讯技术用来搭建无线网络:每个边防哨所都要配备无线电收发器:有一些哨所还可以增配卫星电话. 任意两个配备了一条卫星电话线路的哨所(两边都 ...

  4. 【思维题 线段树】cf446C. DZY Loves Fibonacci Numbers

    我这种maintain写法好zz.考试时获得了40pts的RE好成绩 In mathematical terms, the sequence Fn of Fibonacci numbers is de ...

  5. 14-15.Yii2.0模型的创建/读取数据使用,框架防止sql注入

    目录 创建数据库 表article 配置 db.php 连接数据库 创建控制器 HomeController.php 创建models 创建数据库 表article 1.创建库表 CREATE TAB ...

  6. 编译与安装 OpenSSL

    编译与安装 OpenSSL prefix 是安装目录,openssldir 是配置文件目录,另外建议安装两次,shared 作用是生成动态连接库.linux版的OpenSSL下载地址为:https:/ ...

  7. Post页面爬取失败__编码问题

    python3爬取Post页面时, 报以下错误 "POST data should be bytes or an iterable of bytes. It cannot be of typ ...

  8. lwqq

    源码安装lwqq 加密保存密码 发送截图

  9. SPOJ COT2 Count on a tree II 树上莫队算法

    题意: 给出一棵\(n(n \leq 4 \times 10^4)\)个节点的树,每个节点上有个权值,和\(m(m \leq 10^5)\)个询问. 每次询问路径\(u \to v\)上有多少个权值不 ...

  10. Hive安装步骤

    首先解压压缩包 然后进入bin 执行 ./hive 不过现在hive使用的是自己默认的数据库,不方便,可以通过配置使用MySQL数据库 创建hive-site.xml 粘贴一下内容 <confi ...