Linux内存管理模式,页式管理适合于大块内存的情形,而对于内核对象级别的较小内存情形下,不足以占用1个页。
在linux内核中会有许多小对象,这些对象构造销毁十分频繁,比如i-node,dentry。这么这些对象如果每次构建的时候就向内存要一个页,而其实际大小可能只有几个字节,这样就非常浪费,为了解决这个问题就引入了一种新的机制来处理在同一页框中如何分配小存储器区。这就是我们要讨论的slab层。在讲述slab前,我想先铺垫一下有关内存页的概念,我们都知道在linux中内存都是以页为单位来进行管理的(通常为4KB),当内核需要内存就调用如:kmem_getpages这样的接口(底层调用__alloc_pages())。那么内核是如何管理页的分配的,这里linux使用了伙伴算法。slab也是向内核申请一个个页,然后再对这些页框做管理来达到分配小存储区的目的的。
什么是Slab呢?
最早于1994年在Sun系统中被提出(The Slab Allocator: An Object-Caching Kernel Memory Allocator, Jeff Bonwick (Sun Microsystems)),Slab是一种内存分配器,通过将内存划分不同大小的空间分配给对象使用来进行缓存管理,应用于内核对象的缓存。
A slab is a set of one or more contiguous pages of memory set aside by the slab allocator for an individual cache. This memory is further divided into equal segments the size of the object type that the cache is managing.
Slab的两个主要作用:
- Slab对小对象进行分配,不用为每个小对象分配一个页,节省了空间。
- 内核中一些小对象创建析构很频繁,Slab对这些小对象做缓存,可以重复利用一些相同的对象,减少内存分配次数。
/proc/meminfo的Slab和SReclaimable项
其中Slab=SReclaimable+SUnreclaim
,SReclaimable
表示可回收使用的内存。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26cat /proc/meminfo
MemTotal: 15993324 kB
MemFree: 178448 kB
MemAvailable: 14670236 kB
Buffers: 166740 kB
Cached: 3704632 kB
SwapCached: 0 kB
Active: 3337344 kB
Inactive: 1151668 kB
Active(anon): 717392 kB
Inactive(anon): 116980 kB
Active(file): 2619952 kB
Inactive(file): 1034688 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 236 kB
Writeback: 0 kB
AnonPages: 617560 kB
Mapped: 84988 kB
Shmem: 216732 kB
Slab: 11165136 kB // Slab总量
SReclaimable: 11090552 kB // 可回收Slab量
SUnreclaim: 74584 kB
.............. // 其他信息省略
命令slabtop查看slab占用情况
1 | slabtop |
系统缓存回收机制的设置项
系统默认内存回收配置在/proc/sys/vm/drop_caches
中,除非明确知晓改动对系统全局影响,不建议对此进行修改。
0:不做任何处理,由系统自己管理 1:清空pagecache 2:清空dentries和inodes 3:清空pagecache、dentries和inodes
1 | # cat /proc/sys/vm/drop_caches |
/proc/slabinfo文件信息
在Slab中,可分配内存块称为对象,下图中kmalloc-8
表示每个对象占用8Bit大小的普通Slab,同理kmalloc-16
中每个对象占用16B,依次类推,找出Slab中占用量较大的对象是哪些?
每种对象占用总内存量 = num_objs*objsize
列出几种对象的内存空间占有量:
名称 | 对象数量 | 每个对象大小(B) | 该类型所有对象总量(B) |
---|---|---|---|
ext4_inode_cache | 6168 | 984 | 6069312 |
ext4_inode_cache | 6168 | 984 | 6069312 |
- 统计Slab占用超过100M的对象:
1
# cat /proc/slabinfo |awk '{if($3*$4/1024/1024 > 100){print $1,$3*$4/1024/1024} }'
1 | sudo cat /proc/slabinfo |
总结
上述简要概述了内核Slab内存分配器的作用、意义,如何在Linux中查询、分析当前系统的Slab内存占用情况,从而合理评估系统内存的可用资源。