内存管理——虚拟内存

张嘉倪

现代操作系统都使用了虚拟内存系统来进行内存管理

1. 进程直接访问物理内存造成的问题

早期的操作系统,进程直接访问物理内存,存在以下问题

  • 内存不足
    当进程访问的内存地址超出物理内存范围时,内存不足,程序会崩溃。
    举个例子,32位CPU的系统,地址线为32条,可以访问的寻址空间为 2^{32}=4GB,如果机器只有1GB内存,当进程访问一个超过 1GB 范围的内存地址时,程序崩溃。
  • 内存碎片化
    程序频繁启动和退出,会导致内存的频繁申请和释放,进而产生内存碎片,当进行内存分配申请时,有可能没有任何一块连续的内存区域足够大,而导致分配失败,尽管有足够多的碎片,总量超过申请量。
  • 内存访问冲突
    多个进程可能访问相同的物理内存地址,造成数据误修改、错乱等。因为进程并不知道哪些内存被占用了。
    如何解决上述这些问题呢?操作系统引入了虚拟内存系统来解决。

2. 什么是虚拟内存

基于以上问题,操作系统使用了虚拟内存的技术方案来进行进程见内存管理。可以理解成进程和物理内存之间的一层映射或容器,进程使用虚拟内存地址,也叫逻辑地址,被MMU硬件单元(Memory Manager Unit)映射到对应的物理内存地址。我们可以看看虚拟内存系统是如何解决上述的直接访问物理内存的问题?

虚拟内存

  • 解决内存不足
    当进程申请内存,发现物理内存不足时,系统会根据页面置换算法把暂时不用的内存置换到硬盘上,并把对应的逻辑地址映射到硬盘,而把释放出来的物理内存返回给最新的进程,并维护该逻辑地址到物理地址的映射关系,产生一种无限内存的错觉。
  • 解决内存碎片
    虚拟内存系统映射表可以找到多块物理内存碎片合并到一个逻辑块中。
  • 内存访问冲突
    不同进程相同的虚拟地址,但是每个进程有自己的映射表,通常会映射到不同的物理内存,不会互相干扰。

有些情况下,进程间需要共享内存,那么就是不同进程的虚拟地址可以映射到相同的物理地址即可。

3. 虚拟内存的原理

3.1 内存分段

最早的虚拟内存管理方式为内存分段的方式,在进程启动时,为进程分配一块连续的内存,划分为代码段、数据段、栈段、堆段等部分,进程维护一个段表,记录每个段在物理内存的起始地址(段基地址)和该段的最大偏移(段界限),虚拟地址由段号和段内偏移值组成,在映射时,根据段号从段表中查询物理地址起始位置,再加上偏移值得到物理内存地址

内存分段

内存分段容易导致两个问题

  • 物理内存容易出现内存碎片
  • 当需要进行内存置换到硬盘时,只能以段为单位,导致内存交换效率较低

3.2 内存分页

为了解决内存分段方案中较大内存碎片内存交换空间大导致效率低的问题,内存分页的方案被提出。该方案的主要做法是:

  • 将整个虚拟和物理内存空间分成若干份固定尺寸的大小,每一份称为一页,通常在 Linux 下,每一页大小为 4KB
  • 虚拟地址和物理地址通过页表来进行映射
    内存分页
3.2.1 如何解决内存分段的大块外部碎片?

内存分页,最小的内存分配单位为页,通常要比段小的多,页之间不需要保证连续,可以将多个不连续的页组装成一块较大的内存区域,因此不会产生大块的外部内存

3.2.2 如何解决内存分段的内存交换效率低问题?

内存分段在产生内存 Swap Out 和 Swap In 到硬盘时,都是以段为单位的,通常较大,而内存分页可以以页为单位,更小更精细,在交换时的效率更高。

3.2.3 虚拟地址如何映射到物理地址

虚拟地址由页号和业内偏移量组成,内存中存放一份页表,保存了虚拟页和物理页的对应关系,根据虚拟地址中的虚拟页号到页表中读取物理页号,再加上虚拟地址中的偏移量,就能得到物理地址


地址映射
3.2.4 内存分页有什么缺陷吗?

(1) 有内部碎片
页的大小固定为4KB,当程序分配的内存需求小于 4KB 时,操作系统也要分配4KB,容易造成页内碎片

(2)页表占用内存较大
页表本身也占用了内存,例如在 32 位环境下,虚拟地址空间为 4GB = 2^{32},一个页大小是 4KB = 2^{12},那么页数为 2^{20}大约为 100 万页,每个页表项需要 4 个字节,则需要 4MB 的空间来存储页表,每个进程都有自己的一份页表,4MB 还是有点大了,我们可以通过多级页表 来减少页表占用的内存大小

3.3 段页式管理

3.3.1 实现方式

分段和分页并不是对立的,Linux 将两种方式组合起来,得到段页式内存管理方案

  • 现将进程内存进行分段、每段有各自的逻辑意义
  • 再将每个段进行分页
  • 虚拟地址由段号、段内页号和页内偏移量组成
  • 每个进程对应一张段表、每个段对应一张页表,段表中的地址为页表的起始地址、页表中的地址为该页的物理地址


    段页式管理
3.3.2 地址映射

段页式内存的地址映射过程:

  • 从虚拟地址中取出段号,访问段表,得到页表起始地址
  • 从虚拟地址中取出段内页号,访问对应的页表,得到物理页号
  • 从虚拟地址中取出页内偏移,和物理页号组合,得到物理地址

4. Linux 程序的内存布局

4.1 用户空间和内核空间

Linux 系统将虚拟地址空间划分为内核空间和用户空间,对于 32 位环境,低地址的 3G 为用户空间,高地址 1G 为内核空间


虚拟内存空间

内核空间和用户空间的区别:

  • 进程在用户态时,只能访问用户空间内存
  • 进程只有进入内核态时,才能访问内核空间内存
    虽然每个进程都有各自独立的虚拟内存空间,但是 <font color=red>每个进程的内核地址,都关联相同的物理内存地址</font>
    进程共享内核物理空间

4.2 用户空间分段

用户空间内存段

用户空间被划分成 6 种不同的内存段

  • 代码段:程序编译后的可执行代码(指令)存放区域,在编译时确定了,同一个程序在不同机器上、在同一个机器上的不同次运行,同一个方法的入口地址都是确定的
  • 数据段:存放程序已初始化的静态常量和全局变量
  • BSS 段:存放未初始化的静态常量和全局变量
  • 堆:动态分配的内存区域,从低地址向高地址增长,大小不固定
  • 栈:存放局部变量、函数调用上下文等,栈的大小在程序启动时就固定了,一般是 8MB,系统提供了参数可以修改
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 计算机系统虚拟内存分享 前言 该分享文档,是基于《深入理解理解计算机系统》第三版关于内存方面的总结。下述所有模型图...
    不想工作的iOS阅读 730评论 0 5
  • 系统中的进程与其他进程共享CPU和主存。首先进程多需要的内存也多,其次内存易被破坏,如进程A不小心写入进程B使用的...
    进击的编程喵阅读 396评论 0 0
  • 虚拟内存的由来 为什么会出现虚拟内存呢?这就要从最初的操作系统来说起了,最初的操作系统并没有现在那么完善,刚开始的...
    tracy_668阅读 4,412评论 0 8
  • [TOC] 为什么不直接使用物理内存 虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续可用的内...
    tracy_668阅读 952评论 0 3
  • 背景 操作系统有虚拟内存与物理内存之分。在虚拟内存出现之前,程序寻址用的都是物理地址,因此程序能寻址的范围是有限的...
    吕信阅读 5,232评论 0 5