kswapd0占用了大量的cpu

kswapd0占据了我的CPU的99.9%,顶级显示我,今天出现的问题是游戏,第一次它在6分钟后消失,现在它已经做了大约20分钟。 这是如何解决的?造成这种情况的原因是什么?

进程kswapd0是管理虚拟内存的进程。 您的机器“应该”在HDD / SSD上有RAM,SWAP和EXT4。 ext4是存储所有内容的地方,从RAM访问总是比较慢。 RAM就像是程序快速访问信息的中途运行空间。 大多数计算机至少有4GB的RAM,这在正常情况下是充足的。 但是,在玩游戏时,您可能会在RAM空间不足,这是SWAP的用武之地。

SWAP是位于您的EXT4旁边的HDD / SSD上的假RAM。 它比EXT4更快,但它比实际RAM慢得多。 当内存不足时,kswapd0会将您未使用/不使用其他程序的程序移动到SWAP,这会导致这些进程出现极端延迟。 如果你的游戏需要5GB内存,那么1GB至少需要SWAP。 这意味着当它试图访问该信息时,它必须等待更长时间才能获得它。

整个过程导致极高的CPU使用率,从SWAP和RAM移动信息以及同时处理信息请求。 如何解决这个问题?

  1. 告诉kswapd0只有当你完全没有RAM时才将东西移动到SWAP。 这是解决SWAP问题的最有效方法。 跑

    echo vm.swappiness=0 | sudo tee -a /etc/sysctl.conf

    其中0100应该使用SWAP的百分比(当你有0%的RAM时,SWAP将开始接收数据)。 您也可以根据自己的喜好编辑/etc/sysctl.conf,而不是每次使用gedit或nano或其他任何东西将此命令添加到它的末尾,但请确保sudo,此文件是root拥有的。 重启,你的设置!

  2. 在运行高内存程序时,减少其他进程的RAM消耗或关闭其他程序。 这就是为什么大多数游戏会告诉您在播放之前关闭所有其他窗口,或者安装也是如此。 像文件同步服务这样的东西往往占用大量内存。
  3. 购买更多内存。 安装RAM并不像听起来那么难。 小隔间上的一个或两个螺钉(如果您在笔记本电脑上)并且只需单击一下即可。 只要确保你买的是正确的!
  4. 降低CPU的进程,就像使用RAM一样。 这将有助于那些RAM到SWAP突发更顺畅。

这是你能做的最好的事情。 其他人可能会说完全禁用交换,但这很危险,我不建议这样做。 如果存在内存泄漏或运行的应用程序太多,这可能会导致整个系统冻结。 只是意识到SWAP是RAM的故障保护。 它绝对不如RAM那么快或高效,但它比Window的Pagefile更好! (完成相同的目的)

编辑:如果您有兴趣了解有关SWAP的更多信息,请参阅此处 。

kswapd0运行在一个CPU的99.9%但实际上根本没有交换

对我来说,它有时会发生在Ubuntu 14.04上,内核3.19.0-50-通用(及更早版本)在VMware vm中运行。 我不知道是什么让它出现了,但是它在空闲时间出现了。

top显示:

 # top top - 09:49:35 up 5 days, 18:35, 1 user, load average: 1.00, 1.00, 0.99 Tasks: 219 total, 2 running, 217 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 25.0 sy, 0.0 ni, 74.7 id, 0.2 wa, 0.0 hi, 0.1 si, 0.0 st KiB Mem: 3028784 total, 1874468 used, 1154316 free, 1010276 buffers KiB Swap: 15624188 total, 3032 used, 15621156 free. 234928 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 52 root 20 0 0 0 0 R 99.7 0.0 122:15.21 kswapd0 3 root 20 0 0 0 0 S 0.3 0.0 0:29.86 ksoftirqd/0 7 root 20 0 0 0 0 S 0.3 0.0 9:49.47 rcu_sched 

临时解决方案

重启解决了问题 – 暂时。

关于serverfault的答案(kswapd在使用交换时经常使用100%CPU)那里我的系统上的设置相同:

 # cat /proc/sys/vm/swappiness 60 # cat /proc/sys/vm/vfs_cache_pressure 100 # cat /sys/kernel/mm/transparent_hugepage/enabled [always] madvise never 

解决方案实际上是# echo 1 > /proc/sys/vm/drop_caches

 # cat /proc/sys/vm/drop_caches 0 # echo 1 > /proc/sys/vm/drop_caches # cat /proc/sys/vm/drop_caches 1 

现在没关系:

 # top top - 10:08:58 up 5 days, 18:55, 1 user, load average: 0.72, 0.95, 0.98 Tasks: 220 total, 1 running, 219 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 0.2 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem: 3028784 total, 681704 used, 2347080 free, 2916 buffers KiB Swap: 15624188 total, 3032 used, 15621156 free. 81924 cached Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 9 root 20 0 0 0 0 S 0.3 0.0 14:10.40 rcuos/0 1 root 20 0 45652 8124 2888 S 0.0 0.3 1:54.98 init 

永久解决方案(待定)?

但由于实际原因尚不清楚,我在网上没有任何合适的解释,这不是一个永久的解决方案。 实际上,选定的答案可能是永久的解决方案。 我只是想添加它以供将来参考,因为重启(使sysctl生效)并不总是可行的。

另一个解决方案可能是将THP设置为madvicenever (请参阅poige对其答案 的评论, 如何修改“/ sys / kernel / mm / transparent_hugepage / enabled”以及禁用透明大页面(THP)上引用的MongoDB手册) )

cron job

我将以下批次设置为cron作为“永久”解决方案:

 #!/bin/bash ## run as cron, thus no $PATH, thus need to define all absolute paths top=/usr/bin/top grep=/bin/grep top=$($top -bn1 -o \%CPU -u0 | $grep -m2 -E "%CPU|kswapd0") IFS=' ' set -f i=0 for line in $top do #echo $i $line if ! (( i++ )) then pos=${line%%%CPU*} pos=${#pos} #echo $pos else cpu=${line:(($pos-1)):3} cpu=${cpu// /} #echo $cpu fi done [[ -n $cpu ]] && \ (( $cpu >= 90 )) \ && echo 1 > /proc/sys/vm/drop_caches \ && echo "$$ $0: cache dropped (kswapd0 %CPU=$cpu)" >&2 \ && exit 1 exit 0 

用。调用

 # mh dom mon dow command * * * * * /bin/bash /path/to/batch/drop_caches.sh >> /var/log/syslog 2>&1 

16.04 14.04 交换