kswapd0进程CPU占用过高 问题通常是发现服务器的内存先呈现出较高的资源占比然后 CPU 资源暴涨导致服务器无法工作。经过查看发现是 kswapd0 进程大量占用 CPU 资源所导致的。图 1 服务器负载情况示意图图中的kswapd0进程是正常的此处仅做展示操作系统会将磁盘的一部分构建为虚拟内存但由于物理内存的速度要远远快于硬盘所以操作系统会通过换页机制来实现物理内存与磁盘的通信。换页机制将暂时不需要的页面换到磁盘中而需要的页面换到内存中。kswapd0进程即为负责换页的。在内存不足时kswapd0会执行换页操作换页的操作。此操作十分占用CPU资源并且由于磁盘的读写速度相较于内存慢上千倍此操作一般会持续进行较长时间从而导致系统出现无法访问之类的似乎卡死的现象。概念物理内存和虚拟内存物理内存(RAM)就是我们通常所理解的通过插入内存条而获得的内存。虚拟内存是将硬盘的一块区域划分出来作为逻辑内存。这部分空间也被称为交换空间swap space。当物理内存不足时可以用虚拟内存代替。swap 分区和物理都有缓存区缓存着之前使用过的数据以便后续快速打开访问。kswapd0Linux uses kswapd for virtual memory management such that pages that have been recently accessed are kept in memory and less active pages are paged out to disk. (what is a page?)…Linux uses manages memory in units called pages. So,the kswapd process regularly decreases the ages of unreferenced pages…and at the end they are paged out(moved out) to disk系统每过一定时间就会唤醒 kswapd看看内存是否紧张如果不紧张则睡眠。在 kswapd 中有2个阀值pages_hige 和 pages_low当空闲内存页的数量低于 pages_low 的时候kswapd 进程就会扫描内存并且每次释放出32个 free pages直到 free page 的数量到达pages_high。所有的进程都需要内存但仅需要将常用的数据块一直保存在内存中而不常用的对象可以在合适的时候读写到硬盘中。基于这点Linux kernel通过采用分页和交换对内存进行调控将进程的部分或全部内存换出到磁盘上释放物理内存以便充分利用物理内存的同时实现对常用文件的快速访问。将上述过程称之为交换区的换进换出swap si/so 。其中 si将分页被重新读取到物理内存。也称作page-in so将内存中要交换的分页写到磁盘上。也称作page-out当物理内存不足时kswapd0 进程会控制持续进行换页操作由于使用swap分区进行数据交换因此 CPU 占用会很高。swappinessLinux 内核会在物理内存不足的时将暂时不用的内存块信息写到交换空间以释放物理内存。vm.swappiness是Linux内核的一个参数用来决定是否进行物理内存和虚拟内存的数据交换。其取值范围为0~100默认值为60表示当物理内存低于40%100-60时使用swap空间。swappiness参数越低表示Linux系统尽量少用swap分区多用物理内存swappiness参数值越高表示使内核更多地去使用swap空间交换的页面文件也越多。查看 swappiness 参数cat /proc/sys/vm/swappiness根据需要修改 swappiness 参数vi /etc/sysctl.conf在sysctl.conf文件中修改vm.swappiness值为合适大小然后保存退出。重新加载sysctl.conf配置文件使其生效sysctl -p通常swap空间设为物理内存的1~2倍。若分配的swap空间太多会浪费磁盘空间太少则会发生错误。系统的物理内存用光的时候系统会跑的很慢由于磁盘的读写速度远远小于物理内存但仍然可以运行。但如果swap空间用光此时的服务进程会出现“application is out of memory”的错误严重时会造成服务进程的死锁。此外若只有一个swap交换区交换操作会使交换区工作变得繁忙而CPU的占用却较小。此时系统大多数时间处于等待状态效率很低。这时候系统的速度取决于IO因为swap交换页面的操作是通过磁盘IO进行的。而如果设置有多个swap交换区swap空间的分配会以轮流的方式操作于所有的swap。大大均衡了IO的负载加快了swap交换的速度。因此swap空间分配设置是非常重要的。buffer/cache在 Linux 的内存管理中buffer 和 cache 分别指 Buffer cache 和 Page cache即缓冲区缓存和页面缓存。在过去buffer 是被用来当成对 io 设备写的缓存而cache 是被用来当作对 io 设备的读缓存。但在当前的内核中page cache 就是针对内存页的缓存即如果有内存是以 page 进行分配管理的都可以使用 page cache 作为其缓存来管理使用当有内存是以块 block 进行分配管理的就会使用 buffer cache 来进行缓存。不过通常的操作下二者是在一起配合产生作用的例如对一个文件进行写入的时候page cache 的内容会被改变而 buffer cache 则负责将 page 标记为不同的缓冲区并记录修改了哪一个缓冲区这样如果后续需要执行脏数据的回写内核就只需要写回修改的部分而不用将整个 page 写回。通常缓存的使用情况如下图所示图 2 服务器内存使用情况示意图Mem 指物理内存total 表示物理内存总量used 表示分配给缓存包括buffers和cached的已使用的内存free 表示未被分配的内存shared 表示多个进程的共享内存buff/cache 是系统分配但未被使用的内存available 表示可用内存。它们之间满足total used free shared buff/cache。真正使用的内存即为 used free shared 部分或 total - buffers/cache的值。建议方案无需干涉停止对于服务器的操作静待换页完成。如上所述修改vm.swappiness参数值释放缓存free -m # 查看当前剩余内存此时窗口会呈现图 2 所示的对话列表用以查看内存的使用情况。/proc是一个虚拟文件系统可以通过修改/proc中的文件来对当前kernel的行为做出调整。因此我们可以通过调整/proc/sys/vm/drop_caches来释放内存。操作如下sync # 写缓存到文件系统 echo 1 /proc/sys/vm/drop_caches # 释放内存 echo 0 /proc/sys/vm/drop_caches # 释放完内存后把drop_caches值改回去让系统重新自动分配内存需要注意的是一般情况下系统将内存管理的很好我们在生产环境中的服务器不要频繁的去释放内存只在必要时候清理内存即可。主要应该考虑的是从应用程序层面去优化内存的利用和释放其他的交给操作系统自己来管理。