本文解释linux内存中swappiness的作用,以及linux内存中swappiness=0究竟意味着什么。

内存回收

我们都知道,Linux一个进程使用的内存分为2种:

  1. file-backed pages(有文件背景的页面,比如代码段、比如read/write方法读写的文件、比如mmap读写的文件;他们有对应的硬盘文件,因此如果要交换,可以直接和硬盘对应的文件进行交换),此部分页面进page cache

  2. anonymous pages(匿名页,如stack,heap,CoW后的数据段等;他们没有对应的硬盘文件,因此如果要交换,只能交换到虚拟内存-swapfile或者Linux的swap硬盘分区),此部分页面,如果系统内存不充分,可以被swap到swapfile或者硬盘的swap分区

因此,Linux在进行内存回收(memory reclaim)的时候,实际上可以从1类和2类这两种页面里面进行回收,而swappiness就决定了回收这2类页面的优先级。

swappiness越大,越倾向于回收匿名页;swappiness越小,越倾向于回收file-backed的页面。当然,它们的回收方法都是一样的LRU算法。

swappiness=0的历史与现在

在Linux的早期版本(2012年以前的版本,kernel 3.5-rc1),哪怕swappiness被设置为0,其实匿名页仍然有被交换出去的机会:

早先的回收权重是这样计算的:

anon_prio = swappiness;

file_prio = 200 - anon_prio;

ap = (anon_prio + 1) * (reclaim_stat->recent_scanned[0] + 1);

fp = (file_prio + 1) * (reclaim_stat->recent_scanned[1] + 1);

由此可看出,哪怕swappiness为0,ap也是不会为0的,只是比较小。所以swappiness=0不意味着匿名页就不交换。

2012年的第一场雪,比以往时候来得更晚一些

这一年,一个小小的提交,引发了蝴蝶效应,并震惊寰宇:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fe35004fbf9eaf67482b074a2e032abb9c89b1dd

它彻底改变了swappiness=0的定义。这个commit,碧血横飞,浩气四塞,草木为之含悲,风云因而变色。

它的意思再明确不过,如果swappiness=0,除非系统的内存过小(nr_free + nr_filebacked < high watermark)这种恶劣情况发生,

都只是考虑交换file-backed的pages,就不会考虑交换匿名页了。

它改动的代码如下:

-ap = (anon_prio + 1) * (reclaim_stat->recent_scanned[0] + 1);

+ap = anon_prio * (reclaim_stat->recent_scanned[0] + 1);

ap /= reclaim_stat->recent_rotated[0] + 1;

-fp = (file_prio + 1) * (reclaim_stat->recent_scanned[1] + 1);

+fp = file_prio * (reclaim_stat->recent_scanned[1] + 1);

anon_prio如果为0的话,ap也为0了。

于是乎,现在的swappiness如果等于0的话,意味着哪怕匿名页占据的内存很大,哪怕swap分区还有很多的剩余空间,除非恶劣情况发生,都不会交换匿名页,因此这可能造成更大的OOM压力。不像以前,平时会一直兼顾着回收page cache和匿名页。

现在swappiness=0的情况下,天平的格局是:

一石激起千层浪,两指弹出万般音。相关社区的网站内容都跟着进行了更新,比如红帽子:

特洛伊之战中,在决定阿基琉斯和赫克托尔的命运的生死一战中,荷马将命运的天平放在宙斯手中:“天父取出他的那杆黄金天秤,把两个悲惨的死亡判决放进秤盘,一个属阿基琉斯,一个属驯马的赫克托尔,他提起秤杆中央,赫克托尔一侧下倾,滑向哈得斯。”

跨过特洛伊木马屠城千年的悲凉,我们看到Linux里面两位战神的命运,被一个码农轻松地决定。

这个修改引起了一系列的连锁反应,而相关的文档修改,却是发生在2年之后:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8582cb96b0bfd6891766d8c30d759bf21aad3b4d

MEM CGroup里面的swappiness

在使能Memory CGroup的情况下,每个memory group可以设置自己的swappiness值,如果某个group的swappiness被设置为0,这个group的匿名页交换会被完全禁止,从而诱发该group在无file-backed页面可回收情况下(哪怕swap空间还很大)的OOM,这一点透过Documentation/cgroup-v1/memory.txt文档可以看出:

5.3 swappiness

Overrides /proc/sys/vm/swappiness for the particular group. The tunable in the root cgroup corresponds to the global swappiness setting.

Please note that unlike during the global reclaim, limit reclaim enforces that 0 swappiness really prevents from any swapping even if there is a swap storage available. This might lead to memcg OOM killer if there are no file pages to reclaim.

宋宝华:linux内存中 swappiness=0究竟意味着什么?相关推荐

  1. 宋宝华Linux培训笔记-Linux进程管理

    1.cpu进程状态 linux中进程状态如下图: 浅度睡眠为进程等待资源或中断响应,即使资源没有拿到也可以被唤醒:深度睡眠为进程等待资源,拿到资源后进入就绪状态. 僵死状态为进程死亡,但还没有被父进程 ...

  2. 宋宝华Linux培训笔记-Linux多线程

    1.POSIX标准多线程 发送给进程下一组线程的信号将被共享,被其中任意一个线程处理.同一进程创建的线程同生死,如果收到一个kill信号,这一组task_struce都会退出. 2.NPTL模型 内核 ...

  3. 宋宝华- Linux namespace - Docker 背后的故事

    名称空间是在OS之上实现容器与主机隔离,以及容器之间互相隔离的Linux内核核心技术.根据<Docker 最初的2小时(Docker从入门到入门)>一文,名称空间本质上就是在不同的工作组里 ...

  4. linux pdf 宋宝华,51CTO博客-专业IT技术博客创作平台-技术成就梦想

    原创 宋宝华 Linux阅码场 2018-04-10 前言 网上关于BIO和块设备读写流程的文章何止千万,但是能够让你彻底读懂读明白的文章实在难找,可以说是越读越糊涂! 我曾经跨过山和大海 也穿过人山 ...

  5. 宋宝华: 关于DMA ZONE和dma alloc coherent若干误解的彻底澄清

    原创 宋宝华 Linux阅码场 2018-01-22 作者简介 宋宝华,他有10几年的Linux开发经验.他长期在大型企业担任一线工程师和系统架构师,编写大量的Linux代码,并负责在gerrit上r ...

  6. 宋宝华:评Linux 5.13内核

    目录 Misc cgroup Landlock安全模块 系统调用的堆栈随机化 printk无锁ringbuffer的进一步优化 BPF可调用内核函数 公共的IO PAGE Fault支持 Linux ...

  7. 宋宝华:LEP(Linux易用剖析器) 是什么,为什么以及怎么办(2)

    LEP(LINUX EASY PROFILING) 是Linuxer之LEP项目组(Barry Song,Mac Xu,陈松等以及陈莉君教授/西邮Linux 3+1实验室)正在致力于打造的一个开源项目 ...

  8. 宋宝华: 用off-cpu火焰图进行Linux性能分析

    在<宋宝华:火焰图:全局视野的Linux性能剖析>一文中,我们主要看了on-cpu火焰图,理解了系统的CPU的走向的分析.但是,很多时候,单纯地看on-cpu的情况(什么代码在耗费CPU) ...

  9. linux 没有windows.h头文件_宋宝华: Linux内核编程广泛使用的前向声明(Forward Declaration)...

    本文系转载,著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者:宋宝华 来源: 微信公众号linux阅码场(id: linuxdev) 前向声明 编程定律 先强调一点:在一切可 ...

最新文章

  1. linux(ubuntu)~终端(terminal)shell操作指令
  2. Java EE,Docker和Maven(技术提示#89)
  3. 先序中序后序两两结合重建二叉树
  4. 『ExtJS』表单(一)常用表单控件及内置验证
  5. 转载 :配置ssh密钥认证自动登录
  6. C++ 原子操作和内存模型
  7. shell经典面试题根据文件创建用户名及密码(亲测)
  8. SSDB 一个高性能的支持丰富数据结构的 NoSQL 数据库, 用于替代 Redis.
  9. 简记MobileNet系列
  10. omnigraffle 画曲线_OmniGraffle使用的10个小技巧
  11. 【进阶修炼】——改善C#程序质量(5)
  12. python 车牌识别简单_如何用 Python 识别车牌
  13. 游戏框架(Unity3D游戏客户端基础框架)
  14. mpg文件怎么转换成mp4
  15. 复联4定档 4.24——十一年21部漫威电影,用数据为你梳理口碑、票房、主演最佳...
  16. chromecast 断电重启后时间错误
  17. ElementPlus 侧边栏右侧空隙
  18. win10+黑苹果 单硬盘的双系统引导配置
  19. stm32报错:identifier is undefined总结
  20. windows10计算机放桌面,将win10计算器放在桌面上的操作方法

热门文章

  1. python历史波动率_历史波动率计算问题?
  2. 3dmax插件开发环境配置及FileExport和Utilities模板测试
  3. 3dmax插件导出x格式异常
  4. ios按钮点击实现android反馈,iOS开发APP内部实现点击按钮切换语言
  5. linux 修改 usb-serial.c 提升3G上网速度
  6. 【爬虫实战】国家企业公示网-运行效果
  7. JavaWeb——grid布局
  8. mtp usb驱动 v4.9 最新版
  9. stm8L 初始化系统时钟
  10. echarts数据可视化项目经验积累