缓存使用率过高导致速度变慢

缓存使用率过高导致速度变慢

我正在尝试找出导致我的个人电脑运行极其缓慢的罪魁祸首。最大的嫌疑是内存。当电脑运行速度很快时,我的缓存内存看起来正常。然而,当它运行缓慢时,它看起来是这样的:

luke@Luke-XPS-13:~$ free -m
              total        used        free      shared  buff/cache   available
Mem:           7830        1111        1090         277        5628        1257
Swap:         16077         665       15412

和这个:

luke@Luke-XPS-13:~$ vmstat -S M
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 3  0    665   1065     67   5562    0    0    34    88   43   23 13  4 82  0  0

当所有程序都关闭并且运行后,缓存占用了我 8GB 内存中的 5.5GB

echo "echo 3 > /proc/sys/vm/drop_caches"

应该强制清除它们。一旦计算机开始进入交换状态,其可用速度就结束了。关机暂时解决了问题,但最终问题又出现了,我不知道是什么原因造成的。Slabtop 稍微透露了更多关于罪魁祸首的信息,但我不确定这意味着什么。为什么kmalloc-4096

 Active / Total Objects (% used)    : 1554043 / 1607539 (96.7%)
 Active / Total Slabs (% used)      : 167569 / 167569 (100.0%)
 Active / Total Caches (% used)     : 76 / 109 (69.7%)
 Active / Total Size (% used)       : 5091450.96K / 5105920.97K (99.7%)
 Minimum / Average / Maximum Object : 0.01K / 3.18K / 18.50K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
1254755 1254755 100%  4.00K 156847        8   5019104K kmalloc-4096
  5430   5430 100%    2.05K    362       15     11584K idr_layer_cache
 20216   9010  44%    0.57K    722       28     11552K radix_tree_node
  8820   7358  83%    1.05K    294       30      9408K ext4_inode_cache
 38577  25253  65%    0.19K   1837       21      7348K dentry
 12404  11432  92%    0.55K    443       28      7088K inode_cache
 30120  29283  97%    0.20K   1506       20      6024K vm_area_struct
 31722  31722 100%    0.12K    933       34      3732K kernfs_node_cache
 13696  12514  91%    0.25K    856       16      3424K kmalloc-256
 27144  27134  99%    0.10K    696       39      2784K buffer_head
 41088  29789  72%    0.06K    642       64      2568K kmalloc-64
   632    567  89%    3.75K     79        8      2528K task_struct
  2432   2274  93%    1.00K    152       16      2432K kmalloc-1024
  3048   2677  87%    0.64K    127       24      2032K shmem_inode_cache
   912    845  92%    2.00K     57       16      1824K kmalloc-2048
   172    162  94%    8.00K     43        4      1376K kmalloc-8192
  1736   1561  89%    0.56K     62       28       992K ecryptfs_key_record_cache
  5103   4073  79%    0.19K    243       21       972K kmalloc-192
  1792   1626  90%    0.50K    112       16       896K kmalloc-512
  1456   1456 100%    0.61K     56       26       896K proc_inode_cache
 10149   8879  87%    0.08K    199       51       796K anon_vma
 24960  19410  77%    0.03K    195      128       780K kmalloc-32
   360    352  97%    2.06K     24       15       768K sighand_cache

答案1

根据您的评论,您说当您尝试echo 3 > /proc/sys/vm/drop_caches

这只有在写入缓存时才会发生。如果您向某些文件写入 5 GB,数据会立即进入缓存,程序将继续运行。缓存实际上是在后台以最快的速度写入存储。在您的情况下,存储似乎非常慢,并且您会积累未写入的缓存,直到它耗尽所有 RAM 并开始将所有内容推送到交换区。

内核永远不会将缓存写入交换分区。它会将其保存在 RAM 中,直到安全地写入目标为止。

内核永远不会删除未写入的缓存,因为这会导致数据丢失(您已经保存了一个文件,因此您希望数据能够进入永久存储器)。

您只能通过加快存储速度来解决这个问题。此问题通常出现在通过网络安装的存储(请检查您的mount类型cifs、、等)或速度较慢的 USB1 设备上。nfssshfs

sysctl vm.dirty_ratio=10您还可以在脏缓存增长过多之前限制其大小,从而减轻系统出现问题的严重性。

脏值

包含可用页面和可回收页面的总可用内存的百分比,包含生成磁盘写入的进程本身将开始写出脏数据的页面数。

总可用内存不等于总系统内存。

如果诊断正确,您将发现缓存很容易被丢弃(至少 90%),并且写入这些 GB 的过程变得非常缓慢。系统的其余部分将变得更具响应性。

答案2

我建议以下几点:

  1. 检查cat /proc/meminfo和检查MemAvailableShmem如果你运行的软件使用大量共享内存,这将计入Cached但这不是传统意义上的缓存,当需要更多 RAM 时可以丢弃它。请参阅讨论https://lkml.org/lkml/2021/8/30/635有关详细信息。MemAvailable通常是实际可用内存的更好指标,可以通过立即删除所有可能的缓存并一起使用所有可用内存来获得。请注意,这MemAvailable是一个统计数据,而不是确切的值,因此对于非常尖锐的内存使用情况,它可能会滞后一点。

  2. 尝试增加/proc/sys/vm/vfs_cache_pressure。默认情况下,这是100,但如果内存不足,您可以尝试增加这个值(例如echo 150 > /proc/sys/vm/vfs_cache_pressureroot。理论上,这应该以牺牲性能为代价,通过减少磁盘缓存来增加应用程序可用的 RAM。这将降低您的整体磁盘吞吐量,但可以在 RAM 不足的情况下减少最坏情况下的延迟。

  3. 运行cat /proc/buddyinfo并验证您是否有所有块大小的可用块。基本上,任何带有单词的行在Normal任何列中都不应有零。如果您有零,特别是在行尾附近,并且在开头有大数字,则您的系统正在遭受内存碎片化。如果您遭受内存碎片化,您可以尝试运行echo 1 > /proc/sys/vm/compact_memory以强制内核立即运行内存碎片整理例程。如果这有助于系统在短时间内的性能,那么您的系统正在遭受内存碎片化,您应该尝试使用更多的 CPU 能力来更频繁地自动压缩内存或修复导致严重碎片化的软件。有些人最终添加了一个cron作业来compact_memory每 N 分钟回显 1,但我认为这是一种粗暴的解决方法,而不是真正的解决方案。

相关内容