问题描述与定位
问题:监控报警内存使用率过高达到了90%,但使用top命令查看总占用量为一般,没有打到80%。(在此之前,服务器上做过备份之后内存就一直上升,但以结束)
![](https://img.haomeiwen.com/i15150050/df9b1b4c7a3287da.png)
看到这里我很疑惑,于是又用free查了一下发现,使用率确实很高
![](https://img.haomeiwen.com/i15150050/771637fbfce78857.png)
经查询无论是top命令还是ps命令,能查询到的都是用户态,而free命令可以显示当前整体的使用情况。想要查看到详细信息使用以下命令:
cat /proc/meminfo
MemTotal: 1015024 kB
MemFree: 491112 kB
MemAvailable: 754716 kB
Buffers: 62280 kB
Cached: 299528 kB
SwapCached: 0 kB
Active: 260060 kB
Inactive: 166540 kB
Active(anon): 65016 kB
Inactive(anon): 244 kB
Active(file): 195044 kB
Inactive(file): 166296 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 168 kB
Writeback: 0 kB
AnonPages: 64808 kB
Mapped: 24220 kB
Shmem: 472 kB
Slab: 70064 kB 内核数据结构缓存的大小,可以减少申请和释放内存带来的消耗
SReclaimable: 60076 kB 可收回Slab的大小
SUnreclaim: 9988 kB 不可收回Slab的大小(SUnreclaim+SReclaimable=Slab)
经过查看slab使用量过大,当时占用量为38%,这就解释了多出来的内存消耗用来干什么了
slab
slab是分配内核内存的第二种策略每个 slab 由一个或多个物理连续的页面组成,每个 cache 由一个或多个 slab 组成,每个内核数据结构都有一个 cache。像file_struct superblock等一些列涉及文件的内核态结构体都会用到slab,也就是说之前涉及到了文件操作一开始都要先到内存,操作完成后会刷新到磁盘,之后,内核跟踪slab的计数器变为0后安全的释放掉slab的存储。
查看slab的使用情况,根据内存占用大小排序
slabtop -o -sc
Active / Total Objects (% used) : 226782 / 228255 (99.4%)
Active / Total Slabs (% used) : 9027 / 9027 (100.0%)
Active / Total Caches (% used) : 74 / 97 (76.3%)
Active / Total Size (% used) : 67222.33K / 67651.38K (99.4%)
Minimum / Average / Maximum Object : 0.01K / 0.30K / 8.00K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
33435 33435 100% 1.01K 2229 15 35664K ext4_inode_cache
61173 61173 100% 0.19K 2913 21 11652K dentry
8827 8827 100% 0.58K 679 13 5432K inode_cache
34983 34983 100% 0.10K 897 39 3588K buffer_head
3346 3346 100% 0.57K 239 14 1912K radix_tree_node
12648 12648 100% 0.12K 372 34 1488K kernfs_node_cache
1572 1544 98% 0.64K 131 12 1048K proc_inode_cache
1040 1033 99% 1.00K 130 8 1040K kmalloc-1024
4122 4118 99% 0.21K 229 18 916K vm_area_struct
119 108 90% 4.06K 17 7 544K task_struct
13566 13566 100% 0.04K 133 102 532K ext4_extent_status
264 240 90% 2.00K 33 8 528K kmalloc-2048
780 780 100% 0.66K 65 12 520K shmem_inode_cache
7872 7872 100% 0.06K 123 64 492K kmalloc-64
195 195 100% 2.06K 13 15 416K idr_layer_cache
10098 8976 88% 0.04K 99 102 396K selinux_inode_security
96 85 88% 4.00K 12 8 384K kmalloc-4096
1504 1347 89% 0.25K 94 16 376K kmalloc-256
4386 4386 100% 0.08K 86 51 344K Acpi-State
40 24 60% 8.00K 10 4 320K kmalloc-8192
544 523 96% 0.50K 68 8 272K kmalloc-512
1344 1344 100% 0.19K 64 21 256K kmalloc-192
105 105 100% 2.06K 7 15 224K sighand_cache
4335 4335 100% 0.05K 51 85 204K shared_policy_node
1887 1887 100% 0.08K 37 51 148K anon_vma
1344 1344 100% 0.09K 32 42 128K kmalloc-96
133 133 100% 0.81K 7 19 112K task_xstate
解决
1.清除slab缓存
了解到是Slab导致的占用内存过高的问题之后,可以手动的刷Slab,操作如下:
echo 3 > /proc/sys/vm/drop_caches
0:不做任何处理,由系统自己管理
1:清空pagecache
2:清空dentries和inodes
3:清空pagecache、dentries和inodes
但这种操作是不安全的,最好还是应该通过cat /proc/slabinfo擦看到信息,了解到应用程序进行什么操作,导致内核频繁申请结构体导致Slab占用大量内存,看能否避免这样的问题,同时,内核有自动回收机制,可修改触发自动回收的阀值,当slab空闲内存达到一定量的时候,进行有效的回收。
2.系统的自动slab缓存回收
在slab缓存中,对象分为SReclaimable(可回收)和SUnreclaim(不可回收),而在系统中绝大多数对象都是可回收的。内核有一个参数,当系统内存使用到一定量的时候,会自动触动回收操作。
内核参数:
vm.min_free_kbytes = 836787
代表系统所保留空闲内存的最低限。
查看
sudo sysctl -a | grep free_kbytes
vm.min_free_kbytes = 45056
修改
echo "vm.min_free_kbytes = 65056" /etc/sysctl.conf
sysctl -p
参考文档
https://blog.csdn.net/weixin_41944449/article/details/88028252#fn1
https://www.iteye.com/blog/fengbin2005-2218722
https://www.linuxidc.com/Linux/2014-08/105920.htm
网友评论