内存优化之KSM技术

 

KSM是什么

KSM是linux中针对重复数据进行合并并删除冗余数据的一种内存节约技术,全称是Kernel Samepage Merging。

于linux 2.6.32引入,最初设计用于虚拟机,通过合并内存页来增加并发虚拟机的数量。但在非虚拟环境下仍然有用。通过合并相同的物理页来达到节省内存的效果。

更多详细的特性可以参考: https://www.kernel.org/doc/html/next/mm/ksm.html

 

KSM的原理

原理:通过扫描内存区域,找到并合并相同的内存页面,实现节省内存的技术 

如果KSM被编译进了内核,内核在启动后会创建ksmd内核线程,周期性扫描用户内存,寻找可以合并的相同的内存页并为写保护页

KSM只会作用于标记为可合并的地址空间

 

核心数据结构 

KSM维护两个红黑树,一颗是稳定树,用来保存稳定合并的唯一页面,另一棵是不稳定树,用来保存合适的候选的可合并页面,每次扫描之后重构,比较两个页面是否相等的方法,直接使用 memcmp 函数。

 

标记可扫描的地址空间的方法,linux提供了系统调用,让用户来指定KSM扫描的地址空间

int madvise(addr, length, MADV_MERGEABLE)

int madvise(addr, length, MADV_UNMERGERABLE)

 

查看linux ksm的指标

 通过命令行 ps aux | grep ksmd 可以打印KSMD的内核进程

 命令行  cat /sys/kernel/mm/ksm/pages_sharing 可以查看当前linuxKSM共享页的数量

/sys/kernel/mm/ksm下包含了整个系统的KSM相关的指标

  pages_to_scan表示KSMD需要扫描多少分页,默认是100

  sleep_millisecs表示文件定义执行另一次页面扫面前KSMD进行睡眠的毫秒数

  max_kernel_pages表示文件定义KSMD可以使用的最大页面数,默认值是可用内存的25%

  pages_to_scan表示文件定义一次给定扫描中可以扫描的页面数

  full_scans表示文件已经执行的全区域扫描的次数

  pages_shared表示KSM正在使用的不可交换的内核页面的数量

  pages_sharing表示一个内存存储指示,多少节点被共享

  pages_unshared 为合并而重复检查的唯一页面的数量

  pages_volatitle表示为频繁改变的页面的数量

  max_page_sharing表示为每一个分页能够运行共享的次数

  merge_across_nodes表示为是否指定多个numa节点的内存进行合并

  run可以设置KSM属性的状态

  use_zero_pages表示为是否合并空白分页,默认是关闭

 

 

 

KSM的案例效果

使用共享内容KSM可以小幅度减少同一个业务进程的内存消耗,大幅度减少整机的内存消耗。

其中不支持动态寻路接口的使用,(因为会不同的业务进程会有不同的修改操作)

根据/proc/self/smaps计算的Rss与Pss

Rss:10305.51 MB Pss:10284.62MB

Rss:9701.19 MB Pss:9678.25MB

Rss:8744.93 MB Pss:704.89MB

 

 

KSM的应用

在测试环境中,可以直接开启,为了让同一台机器可以容纳更多的实例。

在生产环境中,需要针对不同的应用场景来设定

对于延迟敏感型的应用,极限开启KSM会遇到SWAP频繁使用,影响应用执行的问题。开启KSM要注意最大使用的边界,确保不会导致SWAP的使用,同时,开启KSM也能留出更多内存,以应付应用的内存泄露等问题留出更多的团队反应时间。

对于

 

posted @ 2024-12-07 11:35  zhang--yd  阅读(36)  评论(0编辑  收藏  举报