点我查看秘籍连载

OOM和swap分区

进程的虚拟内存空间是映射到整个物理内存空间的,所以在进程自身看来它拥有了整个物理内存,它也能使用整个物理内存,只需在使用的时候请求操作系统帮忙分配更多空间即可。

但是,操作系统上并非只运行了一个进程,如果一个进程无休止的申请物理内存空间,最终会导致物理内存耗尽或即将耗尽,使得操作系统无法创建新进程,因为创建新进程需要为它分配虚拟内存。

所以,操作系统必须得监视物理内存的使用情况,在出现物理内存耗尽或即将耗尽的时候,如果进程继续请求分配内存,将报错out-of-memory(OOM)表示内存不足,并且在出现OOM的时候,操作系统将触发OOM Killer程序从进程列表中筛选出一个内存密集型进程杀掉,从而释放大片内存。但显然,这是不怎么友好的方式,不少服务器都专门或主要运行一个服务,如果这个服务进程正好申请了大量内存,它很可能会被OOM Killer杀掉,从而导致服务停止。

其实,早期内存一般都比较小,很容易就出现内存不足的问题,所以很早就提出了一个交换分区(swap partition)的概念。

swap分区是将磁盘当作内存使用,使得虚拟地址空间的范围大小可以超出物理内存的实际大小,在物理内存空间不足时,可以将物理内存中的一些不重要数据拷贝到磁盘的swap分区中,从而让出内存空间,并且在需要那些已被拷出数据时再从swap分区中拷回到内存,从而不再那么容易发生OOM错误。

但是swap分区毕竟是在磁盘上,并且要在内存和磁盘之间传递数据,所以要访问swap分区上的数据时速度会非常慢。在目前大内存都已足够廉价的情况下,已经没有多少必要使用swap分区。

虽然,现在swap分区对进程来说很少派上用场,但涉及到的一些技术和概念有必要简单介绍下。

使用swap分区第二个要解决的问题是,如何让虚拟地址空间的页映射到磁盘swap分区的页上。也就是,如何将虚拟页翻译成swap页,并且在访问时怎么知道这不是内存的物理页。

因为在物理内存的基础上引入了swap分区,所以每个虚拟页中都有一个存在位来表示该页是否存在于内存中,如果该位的值为1,表示驻留在内存中,如果为0则表示在swap分区而非内存。其中,所有驻留在内存中的页也称为驻留集(Resident Set)。

当访问一个虚拟页的时候,如果发现不在内存中,这时候会产生缺页异常(page fault),也称为页未命中(page miss),于是陷入操作系统,启动页错误处理程序,从swap分区中找到对应的页(显然,这里需要将虚拟内存页翻译成swap分区页的地址)并拷贝到内存中。从swap分区拷入页的过程称为换入页(page in)。

这里产生了一个新问题,既然已经使用了swap分区,说明此时物理内存已经处于紧张状态,从swap中page in的页如何放进内存中?其实,这里也需要先进行page out,将该进程的一页或多页page out以便腾出内存。那么哪些运气不好的页会被page out呢?这里又出现了策略算法,称为页替换策略算法,用来决定哪些页应该被page out,比如使用FIFO算法换出那些先进入的页,使用随机算法随机选择换出的页,使用LRU算法选择最近最不常用的页等等。

其实,除了page out换出页腾出少量内存空间外,操作系统还设置了两个关于空闲页数量(显然,这是物理页)的水位线:高水位线(High Watermark,HW)和低水位线(Low Watermark,LW)。当操作系统发现空闲页的数量少于低水位线的值时,就会自动启动一个称为swap daemon(也称为page daemon)的后台线程kswapd,该线程会扫描所有进程并从中选出一些候选进程,然后将这些进程的所有页都拷贝到swap分区,直到空闲物理内存页的数量达到高水位线的值。

提示:高水位线和低水位线

在计算机领域中,常会使用高水位线和低水位线来监视进程的一些可用性资源。当这类可用性资源的数量高于或临近高水位线的值时,表明资源充足。当可用性资源的数量已经低于低水位线,说明资源紧张,应当采取一些措施恢复一些资源。

其中,换出进程所有页到swap分区的过程称为swap out,而从swap分区拷入进程所有页的过程(比如再次调度到该进程)称为swap in。将这两个概念与page out和page in区分以下:

  • page in和page out是拷入或拷出进程的一页或某些页
  • swap in和swap out是拷入或拷出进程的所有页

关于swap分区,能不用的话最好还是不用,因为当真正用到swap分区的时候,内存已经进入了紧张状态,之后的绝大多数进程基本上都会涉及到swap分区,不断地出现page fault而进行换页,这会导致进程抖动(thrashing),使得整体效率低下,而且这个状态是持续的,直到释放足够的内存空间。这时候还不如采取其它办法释放内存空间,例如杀掉某些无关进程、重启内存密集型服务、重启机器等。

每天3分钟操作系统修炼秘籍(12):OOM和swap分区的更多相关文章

  1. 每天3分钟操作系统修炼秘籍(14):IO操作和DMA、RDMA

    点我查看秘籍连载 I/O操作和DMA.RDMA 用户进程想要执行IO操作时(例如想要读磁盘数据.向磁盘写数据.读键盘的输入等等),由于用户进程工作在用户模式下,它没有执行这些操作的权限,只能通过发起对 ...

  2. 每天3分钟操作系统修炼秘籍(6):Idle进程

    点我查看秘籍连载 CPU的归属:Idle进程 操作系统并不总是繁忙.例如个人PC上任务比较轻,多数时候都无法充分利用CPU,导致CPU处于空闲状态.但CPU既然通电了,它就得运行,那么在它没有任务需要 ...

  3. 每天3分钟操作系统修炼秘籍(13):两个缓冲空间Kernel Buffer和IO Buffer

    两个缓冲空间:kernel buffer和io buffer 先看一张图,稍后将围绕这张图展开描述.图中的fd table.open file table以及两个inode table都可以不用理解, ...

  4. Vim修炼秘籍之语法篇

    前言 少年,我看你骨骼精奇,是万中无一的武学奇才,维护世界和平就靠你了,我这有本秘籍<Vim修炼秘籍>,见与你有缘,就十块卖给你了! 如果你是一名 Vimer,那么恭喜你,你的 Vim 技 ...

  5. CH01-ZYNQ修炼秘籍-LINUX篇-虚拟机环境搭建

    CH01基于Ubuntu系统的ZYNQ-7000开发环境的搭建 1.1概述 实验环境: Windows 10 专业版 Vmware workstation 14.1.1 Ubuntu 16.04.3 ...

  6. 操作系统开发系列—12.f.在内核中添加中断处理 ●

    因为CPU只有一个,同一时刻要么是客户进程在运行,要么是操作系统在运行,如果实现进程,需要一种控制权转换机制,这种机制便是中断. 要做的工作有两项:设置8259A和建立IDT. /*========= ...

  7. 操作系统开发系列—12.c.从Loader加载ELF内核,顺便解释下函数调用过程 ●

    实际上,我们要做的工作是根据内核的Program header table的信息进行类似下面这个C语言语句的内存复制: memcpy(p_vaddr, BaseOfLoaderPhyAddr+p_of ...

  8. MySQL DBA修炼秘籍

    0.导读 本文主要写给那些立志成为MySQL DBA,以及正在学习MySQL的同行们,结合个人及业内其他同行的职业发展经历给大家一些参考,如何成为合格的MySQL DBA. 1.什么是MySQL DB ...

  9. Vim技能修炼教程(12) - Vim的脚本语言支持

    Vim的脚本语言支持 本节开始,我们正式接触vimscript这门古老的脚本语言. 首先要说明,vim支持的扩展语言很多,比如python, python3, ruby, lua,tcl等常见脚本语言 ...

随机推荐

  1. PHP自动发红包代码示例

    <?php header('Content-type:text'); define("TOKEN", "weixin"); $wechatObj = ne ...

  2. 基于PyTorch实现MNIST手写字识别

    本篇不涉及模型原理,只是分享下代码.想要了解模型原理的可以去看网上很多大牛的博客. 目前代码实现了CNN和LSTM两个网络,整个代码分为四部分: Config:项目中涉及的参数: CNN:卷积神经网络 ...

  3. ThinkPHP5——模型关联(一对多关联)

    关联定义 一对多关联的情况也比较常见,使用hasMany方法定义,参数包括: hasMany('关联模型名','外键名','主键名',['模型别名定义']); 例如租客表和宿舍表,一个宿舍有多个租客, ...

  4. Thinkphp5——pathinfo的访问模式、路径访问模式

    tp5访问入口文件的时候是,访问public目录下的index.php,那么她真正访问的url到底是什么?如何去访问其他页面,实际上她默认使用的PATH_INFO模式进行访问. PATHINFO模式 ...

  5. luogu P2946 [USACO09MAR]牛飞盘队Cow Frisbee Team

    题目背景 老唐最近迷上了飞盘,约翰想和他一起玩,于是打算从他家的N头奶牛中选出一支队伍. 每只奶牛的能力为整数,第i头奶牛的能力为R i .飞盘队的队员数量不能少于 1.大于N.一 支队伍的总能力就是 ...

  6. UIContainerView纯代码实现及原理介绍

    UIContainerView纯代码实现及原理介绍 1.1-在StoryBoard中使用UIContainerView 1.2-纯代码使用UIContainerView 1.3-UIContainer ...

  7. iOS libsqlite3.0.tbd和libsqlite3.tbd的区别

    ibsqlite3.0.tbd 只是一个快捷方式,其实也是指向libsqlite3.tbd的,如果libsqlite3.0.tbd指向的就是最新的libsqlite3.tbd,就不用更新了.

  8. three.js各种材质的实现源码

    three.js常用材质:基本材质.兰伯特材质.冯氏材质.标准材质. 我们可以自己使用着色器实现这些材质,用于批量渲染等用途. 为了简单,假设物体只有一张漫反射贴图,场景中只存在一个环境光和一个平行光 ...

  9. 图形界面GUI

    JFrame jframe = new JFrame(); //创建一个窗口 jframe.setVisible(true) //设置窗口显示 jframe.setLocation() //设置窗口位 ...

  10. 2019 ICPC南昌邀请赛网络赛比赛过程及题解

    解题过程 中午吃饭比较晚,到机房lfw开始发各队的账号密码,byf开始读D题,shl电脑卡的要死,启动中...然后听到谁说A题过了好多,然后shl让blf读A题,A题blf一下就A了.然后lfw读完M ...