proc_meminfo_SReclaimable_SReclaimable
如下,我们在 slabinfo 能够看到 kmalloc 分成 4 类,分别 cgroup, dma, reclaim, normal 的 kmalloc 版本,其中 kmalloc-xxx 代表默认 normal kmalloc,也就是 在内存压力大时,不能够被回收的内存。kmalloc-rcl-xxx 代表在内存压力大时,能够回收 这部分内存。
在系统启动时,创建各个版本的 kmalloc 并且初始化,其中会将 reclaim kmalloc 的 s->flags
会存储 SLAB_RECLAIM_ACCOUNT
标志。如下:
当调用默认 kmalloc()
分配内存,代表 KMALLOC_NORMAL,不能够被回收的内存。将分配 的内存大小统计到 NR_SLAB_UNRECLAIMABLE_B,即 /proc/meminfo
SUnreclaim 字段。
当调用 kmalloc(__GFP_RECLAIMABLE)
分配内存,代表 KMALLOC_RECLAIM,能够被回收的内存, s->flags
有 SLAB_RECLAIM_ACCOUNT 标志,将分配的内存大小统计到 NR_SLAB_RECLAIMABLE_B, 即 /proc/meminfo
SReclaimable 字段。
如果分配内存大小超过 8KB 以上,以上两种类型的 kmalloc 都调用直接 __kmalloc_large_node()
将分配的内存大小统计到 NR_SLAB_UNRECLAIMABLE_B, 即 /proc/meminfo
SUnreclaim 字段。
只有调用 kmem_cache_create(SLAB_RECLAIM_ACCOUNT)
创建 kmem_cache 时, kmem_cache的 s->flags
才会存储 SLAB_RECLAIM_ACCOUNT 标志,并且 s->allocflags
才会存储 __GFP_RECLAIMABLE
标志。
当调用 kmem_cache_alloc()
时, 如果 kmem_cache s->flags
有 SLAB_RECLAIM_ACCOUNT 标志,将分配的内存大小统计到 NR_SLAB_RECLAIMABLE_B,即 /proc/meminfo
SReclaimable 字段。
否则,将分配的内存大小统计到 NR_SLAB_UNRECLAIMABLE_B,即 /proc/meminfo
SUnreclaim 字段。
注意: __GFP_RECLAIMABLE
对 page 分配器是无效的,只对 slab 分配器有效并且 kmalloc(size <= 8KB)
。
Q:直接调用 page 分配器接口 alloc_pages()
而分配出来的物理页, 为什么都是不能够被回收的?
由于直接调用 page 分配器而分配出来的物理页,没有相关的链表 list 进行管理,所以 不能够被回收。slab 分配器调用 page 分配器来分配物理页,slab 分配页会对分配出来 的物理页,通过链表 list 进行管理,所以能够被回收。
Last updated
Was this helpful?