Linux内存之Slab

文章目录


1. 背景

Linux内存管理模式,页式管理适合于大块内存的情形,而对于内核对象级别的较小内存情形下,不足以占用1个页。
在linux内核中会有许多小对象,这些对象构造销毁十分频繁,比如i-node,dentry。这么这些对象如果每次构建的时候就向内存要一个页,而其实际大小可能只有几个字节,这样就非常浪费,为了解决这个问题就引入了一种新的机制来处理在同一页框中如何分配小存储器区。这就是我们要讨论的slab层。在讲述slab前,我想先铺垫一下有关内存页的概念,我们都知道在linux中内存都是以页为单位来进行管理的(通常为4KB),当内核需要内存就调用如:kmem_getpages这样的接口(底层调用__alloc_pages())。那么内核是如何管理页的分配的,这里linux使用了伙伴算法。slab也是向内核申请一个个页,然后再对这些页框做管理来达到分配小存储区的目的的。

2. 简介

最早于1994年在Sun系统中被提出(The Slab Allocator: An Object-Caching Kernel Memory Allocator, Jeff Bonwick (Sun Microsystems)),Slab是一种内存分配器,通过将内存划分不同大小的空间分配给对象使用来进行缓存管理,应用于内核对象的缓存。

Slab的两个主要作用:

  • Slab对小对象进行分配,不用为每个小对象分配一个页,节省了空间。
  • 内核中一些小对象创建析构很频繁,Slab对这些小对象做缓存,可以重复利用一些相同的对象,减少内存分配次数。

3. 查询

3.1 /proc/meminfo的Slab和SReclaimable项

其中Slab=SReclaimable+SUnreclaim,SReclaimable表示可回收使用的内存。

root@test1:~# cat /proc/meminfo
MemTotal:        2017412 kB
MemFree:          665008 kB
MemAvailable:    1671048 kB
Buffers:          646592 kB
Cached:           456124 kB
SwapCached:         9788 kB
Active:           315296 kB
Inactive:         837060 kB
Active(anon):      28036 kB
Inactive(anon):    22524 kB
Active(file):     287260 kB
Inactive(file):   814536 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:      10485752 kB
SwapFree:       10431480 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:         48168 kB
Mapped:            37248 kB
Shmem:               928 kB
Slab:             122988 kB
SReclaimable:      71000 kB
SUnreclaim:        51988 kB
KernelStack:        5116 kB
PageTables:         4228 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    11494456 kB
Committed_AS:     580256 kB
VmallocTotal:   34359738367 kB
VmallocUsed:           0 kB
VmallocChunk:          0 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
ShmemPmdMapped:        0 kB
CmaTotal:              0 kB
CmaFree:               0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:      323456 kB
DirectMap2M:     1773568 kB
DirectMap1G:           0 kB

3.2 命令slabtop查看slab占用情况

# slabtop
 Active / Total Objects (% used)    : 131433 / 135261 (97.2%)
 Active / Total Slabs (% used)      : 5390 / 5390 (100.0%)
 Active / Total Caches (% used)     : 63 / 87 (72.4%)
 Active / Total Size (% used)       : 28769.26K / 30102.88K (95.6%)
 Minimum / Average / Maximum Object : 0.01K / 0.22K / 8.00K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
 23616  23616 100%    0.21K   1312   18  5248K vm_area_struct
 22080  21832  98%    0.06K    345   64  1380K kmalloc-64
 12831  12080  94%    0.19K    611   21  2444K dentry
 10044  10044 100%    0.11K    279   36  1116K sysfs_dir_cache
  8109   7568  93%    0.08K    159   51   636K selinux_inode_security
  7936   7936 100%    0.06K    124   64   496K anon_vma
  7722   7722 100%    0.10K    198   39   792K buffer_head
  6110   5759  94%    0.58K    470   13  3760K inode_cache
  4732   4694  99%    0.57K    338   14  2704K radix_tree_node
  3072   3072 100%    0.01K  6  512        24K kmalloc-8
  3072   3056  99%    0.96K    384        8  3072K ext4_inode_cache
  2848   2574  90%    0.25K    178   16   712K kmalloc-256
  2380   2380 100%    0.05K     28   85   112K shared_policy_node
  2048   2048 100%    0.02K  8  256        32K kmalloc-16
  2040   1530  75%    0.04K     20  102        80K jbd2_journal_handle
  2016   1615  80%    0.19K     96   21   384K kmalloc-192
  1776   1776 100%    0.64K    148   12  1184K proc_inode_cache
  1288   1288 100%    0.07K     23   56        92K Acpi-ParseExt
  1152   1152 100%    0.03K  9  128        36K kmalloc-32
  1152    832  72%    0.06K     18   64        72K ext4_io_end
  1140   1140 100%    0.66K     95   12   760K shmem_inode_cache
  1072   1053  98%    1.00K    134        8  1072K kmalloc-1024
   960    960 100%    0.12K     30   32   120K kmalloc-128
   672    672 100%    0.09K     16   42        64K kmalloc-96
   432    394  91%    0.50K     54        8   216K kmalloc-512
   408    408 100%    0.04K  4  102        16K Acpi-Namespace
   408    324  79%    0.62K     34   12   272K sock_inode_cache
   352    243  69%    2.00K     44        8   704K kmalloc-2048
   340    340 100%    0.12K     10   34        40K fsnotify_event
   256    256 100%    0.03K  2  128         8K jbd2_revoke_record_s
   256    256 100%    0.02K  1  256         4K jbd2_revoke_table_s
   224    224 100%    0.25K     14   16        56K tw_sock_TCP
   208    208 100%    0.94K     26        8   208K RAW
   190    190 100%    0.81K     10   19   160K task_xstate
   187    154  82%    2.84K     17   11   544K task_struct
   180    180 100%    0.38K     18   10        72K blkdev_requests
   180    180 100%    0.11K  5   36        20K jbd2_journal_head
   180    180 100%    0.13K  6   30        24K ext4_allocation_context
   154    139  90%    1.12K     11   14   176K signal_cache
   150    150 100%    2.06K     10   15   320K idr_layer_cache
   150    143  95%    2.06K     10   15   320K sighand_cache
   128    128 100%    0.06K  2   64         8K kmem_cache_node
   117    117 100%    0.10K  3   39        12K blkdev_ioc
   112    102  91%    4.00K     14        8   448K kmalloc-4096
   110    101  91%    1.56K     11   10   176K mm_struct
   108    108 100%    0.62K  9   12        72K files_cache
    96     96 100%    0.25K  6   16        24K kmem_cache
    96     62  64%    1.88K     12        8   192K TCP
    73     73 100%    0.05K  1   73         4K ip_fib_trie
    64     64 100%    0.25K  4   16        16K dquot
    46     46 100%    0.09K  1   46         4K ext4_xattr
    40     20  50%    8.00K     10        4   320K kmalloc-8192
    25     25 100%    0.16K  1   25         4K sigqueue
    19     19 100%    0.81K  1   19        16K bdev_cache
    16     16 100%    1.88K  2        8        32K blkdev_queue
    15     15 100%    0.26K  1   15         4K numa_policy

3.3 cache查看

free 输出的 Cache,是页缓存和可回收 Slab 缓存的和,你可以从 /proc/meminfo ,直接得到它们的大小:

$ cat /proc/meminfo | grep -E "SReclaimable|Cached" 
Cached:           748316 kB 
SwapCached:            0 kB 
SReclaimable:     179508 kB 

3.4 系统缓存回收机制的设置项

系统默认内存回收配置在/proc/sys/vm/drop_caches中,除非明确知晓改动对系统全局影响,不建议对此进行修改。

0:不做任何处理,由系统自己管理
1:清空pagecache
2:清空dentries和inodes
3:清空pagecache、dentries和inodes

3.5 /proc/slabinfo文件信息

在Slab中,可分配内存块称为对象,下图中kmalloc-8表示每个对象占用8Bit大小的普通Slab,同理kmalloc-16中每个对象占用16
B,依次类推,找出Slab中占用量较大的对象是哪些?

  • 每种对象占用总内存量 = num_objs*objsize

列出几种对象的内存空间占有量:

名称	对象数量	每个对象大小(B)	该类型所有对象总量(B)
ext4_inode_cache	6168	984	6069312
ext4_inode_cache	6168	984	6069312

3.6 统计Slab占用超过100M的对象

cat /proc/slabinfo |awk '{if($3*$4/1024/1024 > 100){print $1,$3*$4/1024/1024} }'
上一篇:【LiteOS】第 2 章


下一篇:Linux内存管理图解