[linux][memory]KSM技术分析

前言: 先来回顾一下Linux平台上的节约内存的方案: swap:通过LRU淘汰掉掉一部分page,把这些page交换到磁盘上。再次访问到这些page的时候,kernel再把它们从磁盘load进内存中。 zram:内存压缩技术。通过压缩lzo算法把页面压缩,也可以节省一部分内存。作者第一次知道zram是在Android中见到的,因为一般的手机使用的emmc flash,是有读写寿命的(作者看到过一份实验数据,某厂家的emmc在连续写入数据三天后,emmc就已经挂了),不能打开swap(因为swap会增加大量的io访问,会让emmc硬件老化更快)。在服务器领域上,作者对这个技术并不是很乐观。 COW:copy-on-write技术,既能减少不必要的运算(这里的减少指的是memory copy;当然,COW触发的时候,需要处理page fault),又能减少内存的使用。 Shared link:用户态能做到的。Linux上几乎所有的程序都需要使用glibc,那么,如果glibc的代码每个进程都拷贝一份,那么就会造成一定的浪费。动态链接技术则可以保证动态链接的程序共享同一份。 Memory balloon:当然,这个技术只针对于云计算平台。作者在《[linux][memory]balloon技术分析》中的解读。 KSM:Kernel Samepage Merging,内核动态计算,找到内核中相同的页面,把相同的页面进程合并。 本文重点解读KSM技术。 设计: 例如Host中运行了多个运行着相同操作系统的Guest OS,那么这些Guest OS中会有很多相同的page,而且很可能是相对稳定的。例如,每个Guest OS都运行着相同的glibc,ld等,而且这些库的代码段和只读数据区都会被映射成只读的page。那么,就可以把这些相同的page做merge操作,节省Host的内存。

所谓merge,就是让多个使用相同page的进程,共享同一个page,把另外的page释放掉。 代码: 代码路径:linux-4.0.4/mm/ksm.c 1,在linux-4.0.4/mm/madvise.c中,

通过MADV_MERGEABLE/MADV_UNMERGEABLE可以建议kernel做merge或者unmerge。 2,在linux-4.0.4/mm/ksm.c中,

主要创建ksm使用的slab,并启动内核线程ksmd。 3,触发ksm_madvise后,__ksm_enter/unmerge_ksm_pages。

4,__ksm_enter中会先把需要做merge的mm插入到链表中,并唤醒ksmd线程。ksmd的核心函数是ksm_do_scan。

首先通过scan_get_next_rmap_item函数获取到需要做merge的page。再通过cmp_and_merge_page函数做merge操作。 5,cmp_and_merge_page函数实现了page merge。 ksm使用的stable tree,是根据page的memcmp组织的红黑树,stable tree中放入stable page。优先判断page是不是已经在stable tree中。如果在stable tree中找到了相同的page,同一个page就不merge了,不是同一个page就在try_to_merge_with_ksm_page函数中做merge。

6,try_to_merge_with_ksm_page函数中,会继续调用try_to_merge_one_page,再调用replace_page。 即使用从stable中的kpage,替换原来的page。并尝试把原来的page释放掉。

7,cmp_and_merge_page还有另外的一个分支:处理unstable tree。

如果page的checksum频繁变化,那就算了,这样的page不适合做merge。 在unstable tree中查找,是否有相同的page。如果没有,把当前page插入unstable tree中就行; 如果在unstable tree中已经有了,那么就尝试merge,然后挪到stable tree中。 8,如果在madvise中选择MADV_UNMERGEABLE,则会触发unmerge_ksm_pages函数。进一步调用到break_ksm函数:

在这里触发handle_mm_fault即可。原理同COW一致。差别在于:COW是由于CPU写page的时候,发现pte中标记的page不可写,会产生一个exception,在处理exception的时候,判断出来是因为COW,则会分配page给进程。 而KSM则是直接选择使用handle_mm_fault来处理。 后记: 作者第一次阅读ZRAM的代码的时候,就被惊讶到一次:原来还可以这么玩~ 后来看到KSM的时候,再次被惊讶到:原来还可以这么玩~ 只能说:别懈怠,技术的路上,不知道的还很多。

原文发布于微信公众号 - AlwaysGeek(gh_d0972b1eeb60)

原文发表时间:2017-01-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Youngxj

emlog文章短网址版权插件

20760
来自专栏BestSDK

一个“爆款”成功的API,都离不开这8条设计准则

我已经看过很多API设计相关的文章和优秀的REST API设计教程。他们通常讨论的是适当的编码技巧和如何在给定的语言中暴露接口。尽管那些是很有用也是很需要的,但...

38970
来自专栏JAVA高级架构开发

Redis 的各项功能解决了哪些问题?

Redis是一个基于BSD开源的项目,是一个把结构化的数据放在内存中的一个存储系统,你可以把它作为数据库,缓存和消息中间件来使用。同时支持strings,lis...

11000
来自专栏杨建荣的学习笔记

使用sysbench压力测试MySQL(二)

昨天有了第一篇的测试之后,仅仅是一个开始。 我接下来做sysbench压测的主要思路是根据现有的配置作出调整,能够持续性的优化和压力测试达到目的,而...

89390
来自专栏技术小黑屋

快速提高Android开发效率的Web工具

在Google的广大支持下,便捷开发Android程序的Native工具层出不穷。其实Android开发涉及到的范围也不小,一些Web工具有时候也会带来事半功倍...

16620
来自专栏腾讯大数据的专栏

大型web系统数据缓存设计

1. 前言 在高访问量的web系统中,缓存几乎是离不开的;但是一个适当、高效的缓存方案设计却并不容易;所以接下来将讨论一下应用系统缓存的设计方面应该注意哪些...

49960
来自专栏信安之路

web测试方法工具篇

之前写过一个文章《web应用渗透测试流程》,这个文章的主要内容是关于一个web应用如何进行测试,测试什么地方,没有过多的提供使用的工具,只是一个针对web测试的...

17400
来自专栏我是攻城师

多线程基础知识了解一下

作为一名优秀的攻城师,了解多线程的知识非常有必要,尤其在人工智能和机器学习的热潮下,如何提高程序或者算法的运行效率是非常有价值的一件事情。

27030
来自专栏Ceph对象存储方案

RGW Bucket Shard设计与优化-上

1 bucket index背景简介 bucket index是整个RGW里面一个非常关键的数据结构,用于存储bucket的索引数据,默认情况下单个bucke...

1.4K50
来自专栏F-Stack的专栏

F-Stack Q&A 第三期

Q1:如果在一个阻塞型的socket上执行recv,会不会把相应的线程卡死,调用recv时该socket中没有数据包,导致sleep,sleep导致该线程没办法...

71590

扫码关注云+社区

领取腾讯云代金券