to be honest, when I first heard about slabs i thought of kitchens, or a bathroom, but not about memory management. but after reading and started learning about it, this term seemed not to be bad for what it stands for. to stay in the context of a kitchen there are different kinds of slabs:
- some maybe appropriate for the floor
- others for the wall
- there are all kinds of colors …
- … all kinds of sizes
- slabs may consist of different materials
- …
and in a way that’s exactly what slabs, in regards to memory management, are about. they provide regions of memory which are fixed in size and for different kinds of tasks.
the basic idea behind slabs is to avoid fragmentation by reserving fixed size memory regions and minimizing the work for allocation and deallocation. the so called constructor is used to initialize areas if memory while the destructor de-initializes them.
while the system is running the kernel requests memory regions of the same size and type over and over again. the process descriptors discussed earlier are one example. if a new process descriptor gets requested the slab allocator is used to get a memory area from cache which fits for holding the structures. once the process terminates and the descriptor can be discarded the memory region will not be deallocated but can be reused when another process needs to get created. in this way the overhead of frequent allocation and deallocation of pages frames can be avoided.
caches & slabs
to check the current caches and slabs you can either directly go to the /proc filesystem:
cat /proc/slabinfo slabinfo - version: 2.1 # name : tunables : slabdata UDPLITEv6 0 0 1024 16 4 : tunables 0 0 0 : slabdata 0 0 0 UDPv6 32 32 1024 16 4 : tunables 0 0 0 :
… or check the current behavior with slabtop:
Active / Total Objects (% used) : 305636 / 315218 (97.0%) Active / Total Slabs (% used) : 11077 / 11077 (100.0%) Active / Total Caches (% used) : 68 / 99 (68.7%) Active / Total Size (% used) : 74608.55K / 76732.62K (97.2%) Minimum / Average / Maximum Object : 0.01K / 0.24K / 8.00K OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME 89193 89192 99% 0.10K 2287 39 9148K buffer_head 55020 54352 98% 0.19K 2620 21 10480K dentry 30260 30247 99% 0.90K 1780 17 28480K ext4_inode_cache 19992 19974 99% 0.08K 392 51 1568K sysfs_dir_cache 17158 16006 93% 0.17K 746 23 2984K vm_area_struct 15360 14165 92% 0.01K 30 512 120K kmalloc-8 10710 10077 94% 0.05K 126 85 504K shared_policy_node 9664 8544 88% 0.06K 151 64 604K kmalloc-64 9051 8118 89% 0.19K 431 21 1724K kmalloc-192 7917 7904 99% 0.59K 609 13 4872K inode_cache
a cache initially does not contain any slabs. slabs will be created once requested and there is no free object to satisfy the request. in this case the cache will grow by n slabs. as with all concurrent access to memory regions caches and slabs are protected by locks, cache spin locks in this case. and when there are locks the must be different states for the objects, that are:
- emtpy
- partial
- full
so what to remember: slabs and caches provide a way to avoid fragmentation and save some work in regards to frequent allocation and deallocation of memory regions. structures that are created and destroyed frequently such as the process or file descriptors benefit from this technique as the requests can be served at much faster time.