分类: LINUX
2010-05-19 20:11:48
小引: 很久很久以前:一个叫做Mark Hemment的哥儿们写了Slab。在接下来的一些年里,其他人对Slab进行了完善。一年半以前,SLOB问世了。SLOB的目标是针对嵌入式系统 的,主要是适用于那些内存非常有限的系统,比如32MB以下的内存,它不太注重large smp系统,虽然最近在这方面有一些小的改进。几个月之前,SLUB闪亮登场。它基本上属于对Slab的重设计(redesign),但是代码更少,并且 能更好的适应large NUMA系统。 SLUB被很认为是Slab和Slob的取代者,内核开发人员称其为:more SMP-friendly SLUB allocator。显然,在桌面平台上的多核心处理器也能从中受益。 在研究SLUB之前,先说说SLAB。众所周知,操作系统进行内存分配的时候,是以页为单位进行的,也可以称为内存块或者堆。但是内核对象远小于页的大 小,而这些对象在操作系统的生命周期中会被频繁的申请和释放,并且实验发现,这些对象初始化的时间超过了分配内存和释放内存的总时间,所以需要一种更细粒 度的针对内核对象的分配算法,于是SLAB诞生了: SLAB缓存已经释放的内核对象,以便下次申请时不需要再次初始化和分配空间,类似对象池的概念。并且没有修改通用的内存分配算法,以保证不影响大内存块 分配时的性能。 由于SLAB按照对象的大小进行了分组,在分配的时候不会产生堆分配方式的碎片,也不会产生Buddy分配算法中的空间浪费,并且支持硬件缓存对齐来提高 TLB的性能,堪称完美。 但是这个世界上没有完美的算法,一个算法要么占用更多的空间以减少运算时间,要么使用更多的运算时间减少空间的占用。优秀的算法就是根据实际应用情况在这 两者之间找一个平衡点。SLAB虽然能更快的分配内核对象,但是metadata,诸如缓存队列等复杂层次结构占用了大量的内存。 SLUB因此而诞生: SLUB 不包含SLAB这么复杂的结构。SLAB不但有队列,而且每个SLAB开头保存了该SLAB对象的metadata。SLUB只将相近大小的对象对齐填入 页面,并且保存了未分配的SLAB对象的链表,访问的时候容易快速定位,省去了队列遍历和头部metadata的偏移计算。该链表虽然和SLAB一样是每 CPU节点单独维护,但使用了一个独立的线程来维护全局的SLAB对象,一个CPU不使用的对象会被放到全局的partial队列,供其他CPU使用,平 衡了个节点的SLAB对象。回收页面时,SLUB的SLAB对象是全局失效的,不会引起对象共享问题。另外,SLUB采用了合并相似SLAB对象的方法, 进一步减少内存的占用。 据内核开发人员称,SLUB相对于SLAB有5%-10%的性能提升和减少50%的内存占用(是内核对象缓存占用的,不是全局哦,否则Linux Kernel可以修改主版本号了)。所以SLUB是一个时间和空间上均有改善的算法,而且SLUB完全兼容SLAB的接口,所以内核其他模块不需要修改即 可从SLUB的高性能中受益。SLUB在2.6.22内核中理所当然的替代了SLAB。 |
|
[11931.178681] LZJ:people_info_cache [11931.178685] LZJ:VMBlockInodeCache [11931.178687] LZJ:blockInfoCache [11931.178688] LZJ:kmalloc_dma-512 [11931.178690] LZJ:RAWv6 [11931.178692] LZJ:UDPLITEv6 [11931.178693] LZJ:UDPv6 [11931.178695] LZJ:tw_sock_TCPv6 [11931.178697] LZJ:TCPv6 [11931.178698] LZJ:flow_cache [11931.178700] LZJ:dm_raid1_read_record [11931.178701] LZJ:kcopyd_job [11931.178703] LZJ:dm_uevent [11931.178705] LZJ:dm_rq_target_io [11931.178706] LZJ:cfq_queue [11931.178708] LZJ:bsg_cmd [11931.178710] LZJ:mqueue_inode_cache [11931.178711] LZJ:fuse_request [11931.178713] LZJ:fuse_inode [11931.178715] LZJ:ecryptfs_inode_cache [11931.178716] LZJ:hugetlbfs_inode_cache [11931.178718] LZJ:jbd2_revoke_record [11931.178720] LZJ:journal_head [11931.178721] LZJ:revoke_record [11931.178723] LZJ:ext4_inode_cache [11931.178725] LZJ:ext4_free_block_extents [11931.178726] LZJ:ext4_alloc_context [11931.178728] LZJ:ext4_prealloc_space [11931.178730] LZJ:ext4_system_zone [11931.178731] LZJ:ext2_inode_cache [11931.178734] LZJ:ext3_inode_cache [11931.178736] LZJ:ext3_xattr [11931.178737] LZJ:dquot [11931.178739] LZJ:posix_timers_cache [11931.178740] LZJ:UDP-Lite [11931.178742] LZJ:UDP [11931.178743] LZJ:tw_sock_TCP [11931.178745] LZJ:TCP [11931.178747] LZJ:sgpool-128 [11931.178748] LZJ:sgpool-64 [11931.178750] LZJ:sgpool-32 [11931.178751] LZJ:sgpool-16 [11931.178753] LZJ:blkdev_queue [11931.178754] LZJ:blkdev_requests [11931.178756] LZJ:biovec-256 [11931.178757] LZJ:biovec-128 [11931.178759] LZJ:biovec-64 [11931.178761] LZJ:bip-256 [11931.178762] LZJ:bip-128 [11931.178764] LZJ:bip-64 [11931.178765] LZJ:sock_inode_cache [11931.178767] LZJ:skbuff_fclone_cache [11931.178769] LZJ:file_lock_cache [11931.178770] LZJ:net_namespace [11931.178772] LZJ:shmem_inode_cache [11931.178773] LZJ:Acpi-Operand [11931.178775] LZJ:Acpi-Namespace [11931.178777] LZJ:taskstats [11931.178778] LZJ:proc_inode_cache [11931.178780] LZJ:sigqueue [11931.178781] LZJ:radix_tree_node [11931.178783] LZJ:bdev_cache [11931.178784] LZJ:sysfs_dir_cache [11931.178786] LZJ:inode_cache [11931.178787] LZJ:dentry [11931.178789] LZJ:buffer_head [11931.178790] LZJ:vm_area_struct [11931.178792] LZJ:mm_struct [11931.178793] LZJ:sighand_cache [11931.178795] LZJ:task_xstate [11931.178796] LZJ:task_struct [11931.178798] LZJ:anon_vma [11931.178800] LZJ:idr_layer_cache [11931.178801] LZJ:kmalloc-8192 [11931.178803] LZJ:kmalloc-4096 [11931.178804] LZJ:kmalloc-2048 [11931.178806] LZJ:kmalloc-1024 [11931.178807] LZJ:kmalloc-512 [11931.178809] LZJ:kmalloc-256 [11931.178810] LZJ:kmalloc-128 [11931.178811] LZJ:kmalloc-64 [11931.178813] LZJ:kmalloc-32 [11931.178814] LZJ:kmalloc-16 [11931.178816] LZJ:kmalloc-8 [11931.178817] LZJ:kmalloc-192 [11931.178819] LZJ:kmalloc-96 [11931.178821] LZJ:number of kmem_cache:86 | people_info_cache0 VMBlockInodeCache1 blockInfoCache2 kmalloc_dma-5123 RAWv64 UDPLITEv65 UDPv66 tw_sock_TCPv67 TCPv68 flow_cache9 dm_raid1_read_record10 kcopyd_job11 dm_uevent12 dm_rq_target_io13 cfq_queue14 bsg_cmd15 mqueue_inode_cache16 fuse_request17 fuse_inode18 ecryptfs_inode_cache19 hugetlbfs_inode_cache20 jbd2_revoke_record21 journal_head22 revoke_record23 ext4_inode_cache24 ext4_free_block_extents25 ext4_alloc_context26 ext4_prealloc_space27 ext4_system_zone28 ext2_inode_cache29 ext3_inode_cache30 ext3_xattr31 dquot32 posix_timers_cache33 UDP-Lite34 UDP35 tw_sock_TCP36 TCP37 sgpool-12838 sgpool-6439 sgpool-3240 sgpool-1641 blkdev_queue42 blkdev_requests43 biovec-25644 biovec-12845 biovec-6446 bip-25647 bip-12848 bip-6449 sock_inode_cache50 skbuff_fclone_cache51 file_lock_cache52 net_namespace53 shmem_inode_cache54 Acpi-Operand55 Acpi-Namespace56 taskstats57 proc_inode_cache58 sigqueue59 radix_tree_node60 bdev_cache61 sysfs_dir_cache62 inode_cache63 dentry64 buffer_head65 vm_area_struct66 mm_struct67 sighand_cache68 task_xstate69 task_struct70 anon_vma71 idr_layer_cache72 kmalloc-819273 kmalloc-409674 kmalloc-204875 kmalloc-102476 kmalloc-51277 kmalloc-25678 kmalloc-12879 kmalloc-6480 kmalloc-3281 kmalloc-1682 kmalloc-883 kmalloc-19284 kmalloc-9685 86 kmem_caches |