zoukankan      html  css  js  c++  java
  • linux下的KSM内存共享机制分析

    2017-04-26


     KSM是内核中的一种内存共享机制,在2.6.36版本的内核中开始引入,简单来说就是其会 合并某些相同的页面以减少页面冗余。在内核中有一个KSM守护进程 ksmd,它定期扫描用户向它注册的内存区,寻找相同的页面,从而用一个添加写保护的页面来代替, 当有进程尝试写入的时候,会自动分配一个新页面,这点就是典型的COW机制。

    KSM最初应用到KVM上,主要作为内存共享,从而腾出更多的可用物理内存,但是事实上,它可以应用于任何应用。KSM仅仅合并匿名页面,不会对文件映射的页面做处理,经过KSM合并的页面最初是被锁定的内存中的,但是现在已经可以像其他页面一样被换出到交换区,但是一经换出,共享的特性就被打破,再次换入的时候,ksmd必须重新对其处理。前面提到,KSM仅仅会扫描那些请求合并的区域,说请求不太合适,就是向KSM模块注册了如果条件允许可以被合并的区域,通过madvise系统调用可以做到这点int madvise(addr, length, MADV_MERGEABLE),同时,应用也可以通过调用int madvise(addr, length, MADV_UNMERGEABLE)取消这个建议从而恢复页面的私有特性,但是该调用可能会突然请求很多内存,超过当前可用的内存额度,造成unmerge失败,很大程度上会造成唤醒Out-Of-Memory killer,杀死当前进程。

    如果KSM没被配置进当前运行的内核,前面提到的madvise调用会失败,如果内核配置了 CONFIG_KSM=y,调用一般会成功,即使KSM守护进程没有运行,不过在进程运行的时候,调用设置的区间范围会被注册进去。

    像其他的madvise调用,它们是应用于用户空间的mmap区域,如果区间包含unmap区域,那么他们就会返回ENOMEM。

    应用在使用KSM的时候要慎重考虑,因为KSM扫描相同的页面会消耗较多的CPU资源,所以一些安装会禁用KSM。KSM守护进程通过sysfs文件系统控制,在/sys/kernel/mm/ksm/下包含有几个文件,所有用户可读但是只有root用户可写

    pages_to_scan   在ksmd睡眠之前,需要扫描多少页面 ,通过echo 100 > /sys/kernel/mm/ksm/pages_to_scan可以修改

    sleep_millisecs   ksmd的睡眠时间,以毫秒为单位。

    merge_across_nodes  控制不同NUMA节点内存的合并,如果被设置成0,则只合并当前NUMA节点的内存。

    run 控制ksmd的运行。0停止ksmd,但是保持合并的页面。1 运行ksmd。2 停止ksmd并unmerge所有合并的页面。

    KSM合并效果实时显示在下面文件:

    pages_shared - how many shared pages are being used
    pages_sharing - how many more sites are sharing them i.e. how much saved
    pages_unshared - how many pages unique but repeatedly checked for merging
    pages_volatile - how many pages changing too fast to be placed in a tree
    full_scans - how many times all mergeable areas have been scanned

    上面字段意义如下A high ratio of pages_sharing to pages_shared indicates good sharing, but a high ratio of pages_unshared to pages_sharing indicates wasted effort.pages_volatile embraces several different kinds of activity, but a high proportion there would also indicate poor use of madvise  MADV_MERGEABLE.

    原文内容见内核文档ksm.txt

  • 相关阅读:
    Gitkraken使用教程
    request.getHeader中区分大小写参数
    MySql 中查询列表中添加序号
    解决windows 下mysql 表名自动转成小写的问题
    MYSQL服务无法启动,服务没有任何错误;解决方法
    idea中设置一键生成方法注释和类注释
    Windows10下安装MySQL8.0.21-64
    navicat连接mysql出现2059错误的解决方法
    解决tomca在eclipse中正常启动,在bin下启动闪退问题
    QT线程的结束
  • 原文地址:https://www.cnblogs.com/ck1020/p/6770272.html
Copyright © 2011-2022 走看看