linux系统编程-内存管理day05

内存锁定

linux实现了请求页面调度(在需要时将页面从硬盘交换进来,当不再需要时再交换出去),这使得系统中进程的虚拟地址空间与实际的物理内存大小没有直接的关系。
交换对进程来说是透明的,应用程序一般都不需要关心内核页面调度的行为。然而在下面两种情况下,应用程序可能希望影响系统的页面调度:

  • 确定性时间约束严格的应用程序需要自己来决定页的调度行为。
  • 安全性:如果内存中含有私人信息,这些信息可能最终被页面调度以不加密的方式储存到硬盘上。在一个高度注重安全性的环境中,这样做可能是不可接收的。这样的应用程序可以请求将密钥一直保留在物理内存上。

  • 注意:虽然内核提供了内存锁定的功能供应用程序在需要的时候使用,但是改变内核的行为可能会对系统整体的表现产生负面的影响。应用的确定性和安全性可能会提高,但是当它的页被锁在了内存中,那另一个应用的页就只能被换出内存。所以,我们应该有选择的去使用内存锁定,而不能盲目地使用。

锁定部分地址空间

POSIX1003.1b-1993定义两个接口将一个或多个页面“锁定”在物理内存,来保证它们不会被交换到磁盘。

  1. mlock( ):
    mlock( )锁定给定的一个地址空间:
#include <sys/mman.h>
int mlock(const void *addr, size_t len);

调用mlock( )将锁定addr开始长度为len个字节的虚拟内存。成功时函数返回0,失败返回-1,并适当设置errno。

  • 成功调用会将所有包含[addr, addr+len)的物理内存页锁定。(例如,一个调用只是指定了一个字节,包含这个字节的所有物理内存页都将被锁定)。
  • POSIX标准要求addr应该与页边界对齐。Linux没有强制要求,如果真要这样做的时候,会悄悄的将addr向下调整到最近的页面。
  • 一个由fork( )产生的子进程并不从父进程处继承锁定的内存。然而,由于Linux对地址空间COW机制,子进程的页面被锁定在内存中直到子进程对它们执行写操作。
  1. mlockall( ):
    如果一个进程想在物理内存中锁定它的全部地址空间,可以使用mlockall( ):
#include <sys/mman.h>
int mlockall(int flags);

mlockall( )函数锁定一个进程现有的地址空间在物理内存中的所有页面。
flags参数,是下面两个值的按位或操作,用以控制函数行为:(大部分应用程序会同时设定这两个值)

  • MCL_CURRENT: 如果设置了该值,mlockall( )会将所有已被映射的页面(包括栈,数据段,映射文件)锁定进程地址空间中。
  • MCL_FUTURE: 如果设置了该值,mlockall( )会将所有未来映射的页面也锁定到进程地址空间中。

内存解锁

POSIX标准提供了两个接口用来将页从内存中解锁,允许内核根据需要将页换出至硬盘中。

#include <sys/mman.h>
int munlock(const void *addr, size_t len);
in munlockall(void);
  • munlock( )解除addr开始长为len的内存所在的页面地锁定,它消除mlock( )的效果.
  • munlockall( )消除mlockall( )的效果.
    两个函数在成功时都返回0,失败时返回-1.

内存锁定并不会重叠,所以不管mlock( )或mlockall( )了几次,仅一个munlock( )或munlockall( )会解除一个页面的锁定。

linux对于一个进程能锁定的页面数进行了限制:拥有CAP_IPC_LOCK权限的进程能锁定任意多的页面。没有这个权限的进程只能锁定RLIMIT_MEMLOCK个字节,默认情况下,该限制是32KB


判断一个页面在不在物理内存中

mincore( )函数,用来确定一个给定范围的内存是在物理内存中还是被交换到了硬盘中:

#include <unistd.h>
#include <sys/mman.h>
int mincore(void *start, size_t length, unsigned char *vec);

函数通过vec来返回向量,这个向量描述start(必须页面对齐)开始长为length(不需要对齐)字节的内存中的页面的情况。

  • vec的每个字节对应指定区域内的一个页面,第一个字节对应着第一个页面,然后依次对应。
  • vec必须足够大来装入(length - 1 + page_size)/page_size字节。如果页面在物理内存中,对应字节的最低位是1,否则是0。其他的位目前还没有定义。
  • 目前来说,这个系统调用只能用在以MAP_SHARED创建的基于文件的映射上。

投机性存储分配策略

Linux使用投机性分配策略:当一个进程向内核请求额外的内存-如扩大它的数据段,或者创建一个新的存储器映射-内核作出了分配承诺但实际上并没有分给进程任何的物理存储

  • 仅当进程对新“分配到”的内存区域作写操作的时候,内核才履行承诺,分配一块物理内存。内核逐页完成上述工作,并在需要时进行请求页面调度和写时复制。

这样处理有如下几个优点

  1. 延缓内存分配允许内核将大部分工作推迟到最后一刻(当确实需要进行分配时)
  2. 由于请求是根据需求逐页的分配,只有真正需要物理内存的时候才会消耗物理存储
  3. 分配到的内存可能比实际的物理内存甚至比可用的交换空间多的多,这个特征叫超量使用

超量使用和内存耗尽

超量使用的好处:和在应用请求页面就分配物理存储相比,在使用时刻才分配物理存储的过量使用机制允许系统运行更多,更大的应用程序
但是,如果系统中的进程为满足超量使用而申请的内存大于物理内存和交换空间之和,内核只能杀死另一个进程并释放它的内存,以此来满足下一次的分配需求。

  • 当超量使用导致内存不足以满足一个请求时,就发生了内存耗尽(OOM)(out of memory)。
  • 为了处理OOM,内核使用OOM终结者killer来挑选一个进程,并终止它。基于这个目的,内核会尝试选出一个最不重要且又占用很多内存的进程。
关闭超量使用:

内核允许通过文件/proc/sys/vm/overcommit_memory关闭超量使用,和此功能相似的还有sysctl的vm.overcommit_memory参数。

  • 参数默认值为0,告诉内核执行适度的超量使用策略
  • 参数值为1时,确认所有的分配请求
  • 参数值为2时,关闭所有的过量使用,启用严格审计(strict accounting)策略.
严格审计策略:

在严格审计模式中,承诺的内存大小被严格限制在交换空间的大小加上可调比例的物理内存大小。

  • 比例默认为50%,因为物理内存还必须包含着内核,页表,系统保留页,锁定页等等东西。仅它的一部分能够被交换和满足承诺请求。
  • 比例可以在文件/proc/sys/vm/overcommit_ratio里面设置,作用和vm.overcommit_ratio的sysctl参数相似。

使用严格审计策略时要非常小心!许多系统设计者认为严格审计策略才是解决之道,然而,应用程序常常进行一些不必要的、且只有使用超量使用才能满足的分配请求,而允许这种行为也是设计虚拟内存的主要动机之一。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容

  • 操作系统对内存的管理 没有内存抽象的年代 在早些的操作系统中,并没有引入内存抽象的概念。程序直接访问和操作的都是物...
    Mr槑阅读 16,699评论 3 24
  • 1 内存寻址 1.1 物理地址、虚拟地址以及线性地址 物理地址: 物理内存的内存单元地址 虚拟地址: 程序员看到的...
    疯狂小王子阅读 2,812评论 3 21
  • 我是谁? 我感觉我是活在自己的世界里。
    杰克船长就是我阅读 122评论 1 1
  • 你以后会遇见很多人 但你永远都不会见到我了 你可能会发现你身边有那么一个人 有和我相似的一处 但你自习会发现就算有...
    sunninne阅读 341评论 0 1
  • 艳阳依旧笑春风,人约黄昏后。 今年阳节时,景与花依旧。 不见去年人,泪满春衫袖。 佳人已随黄鹤去,新酿青梅为谁盛。...
    般若孤鱼阅读 275评论 0 1