Linux slab 分配器详解

Linux slab 分配器详解

2007-06-14  作者:bitsCN整理  来源:中国网管联盟  点评 投稿 收藏

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script> name="google_ads_frame" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-9969174943212288&dt=1218076870645&lmt=1215165216&output=html&slotname=7776775600&correlator=1218076870645&url=http%3A%2F%2Fwww.bitscn.com%2Flinux%2Fsystem_manage%2F200710%2F116460.html&ref=http%3A%2F%2Fso.bitscn.com%2Fslab.html&frm=0&cc=100&ga_vid=1247841108048580000.1218076871&ga_sid=1218076871&ga_hid=1131419807&flash=0&u_h=900&u_w=1440&u_ah=870&u_aw=1440&u_cd=24&u_tz=480&u_his=1&u_nplug=8&u_nmime=21" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" width="468" frameborder="0" height="15">
<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script> name="google_ads_frame" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-9969174943212288&dt=1218076870697&lmt=1215165216&prev_slotnames=7776775600&output=html&slotname=1613516496&correlator=1218076870645&url=http%3A%2F%2Fwww.bitscn.com%2Flinux%2Fsystem_manage%2F200710%2F116460.html&ref=http%3A%2F%2Fso.bitscn.com%2Fslab.html&frm=0&cc=100&ga_vid=1247841108048580000.1218076871&ga_sid=1218076871&ga_hid=1131419807&flash=0&u_h=900&u_w=1440&u_ah=870&u_aw=1440&u_cd=24&u_tz=480&u_his=1&u_nplug=8&u_nmime=21" marginwidth="0" marginheight="0" vspace="0" hspace="0" allowtransparency="true" scrolling="no" width="300" frameborder="0" height="250">

  良好的操作系统性能部分依赖于操作 系统有效管理资源的能力。在过去,堆内存管理器是实际的规范,但是其性能会受到内存碎片和内存回收需求的影响。现在,Linux? 内核使用了源自于 Solaris 的一种方法,但是这种方法在嵌入式系统中已经使用了很长时间了,它是将内存作为对象按照大小进行分配。本文将探索 slab 分配器背后所采用的思想,并介绍这种方法提供的接口和用法。

网管网www.bitscn.com

  动态内存管理 网管u家u.bitsCN.com

  内存管理的目标是提供一种方法,为实现各种目的而在各个用户之间实现内存共享。内存管理方法应该实现以下两个功能: 网管u家u.bitscn@com

  最小化管理内存所需的时间

网管网www.bitscn.com

  最大化用于一般应用的可用内存(最小化管理开销) 网管网www_bitscn_com

  内存管理实际上是一种关于权衡的零和游戏。您可以开发一种使用少量内存进行管理的算法,但是要花费更多时间来管理可用内存。也可以开发一个算法来有效地管理内存,但却要使用更多的内存。最终,特定应用程序的需求将促使对这种权衡作出选择。 网管u家u.bitscn@com

  每个内存管理器都使用了一种基于堆的分配策略。在这种方法中,大块内存(称为 堆)用来为用户定义的目的提供内存。当用户需要一块内存时,就请求给自己分配一定大小的内存。堆管理器会查看可用内存的情况(使用特定算法)并返回一块内 存。搜索过程中使用的一些算法有 first-fit(在堆中搜索到的第一个满足请求的内存块)和 best-fit(使用堆中满足请求的最合适的内存块)。当用户使用完内存后,就将内存返回给堆。 网管联盟bitsCN_com

  这种基于堆的分配策略的根本问题是碎片(fragmentation)。当内存块被分配后,它们会以不同的顺序在不同的时间返回。这样会在堆中 留下一些洞,需要花一些时间才能有效地管理空闲内存。这种算法通常具有较高的内存使用效率(分配需要的内存),但是却需要花费更多时间来对堆进行管理。

网管u家u.bitsCN.com

  另外一种方法称为 buddy memory allocation,是一种更快的内存分配技术,它将内存划分为 2 的幂次方个分区,并使用 best-fit 方法来分配内存请求。当用户释放内存时,就会检查 buddy 块,查看其相邻的内存块是否也已经被释放。如果是的话,将合并内存块以最小化内存碎片。这个算法的时间效率更高,但是由于使用 best-fit 方法的缘故,会产生内存浪费。

中国网管论坛bbs.bitsCN.com

  本文将着重介绍 Linux 内核的内存管理,尤其是 slab 分配提供的机制。 网管u家u.bitscn@com

  slab 缓存

中国网管论坛bbs.bitsCN.com

  Linux 所使用的 slab 分配器的基础是 Jeff Bonwick 为 SunOS 操作系统首次引入的一种算法。Jeff 的分配器是围绕对象缓存进行的。在内核中,会为有限的对象集(例如文件描述符和其他常见结构)分配大量内存。Jeff 发现对内核中普通对象进行初始化所需的时间超过了对其进行分配和释放所需的时间。因此他的结论是不应该将内存释放回一个全局的内存池,而是将内存保持为针 对特定目而初始化的状态。例如,如果内存被分配给了一个互斥锁,那么只需在为互斥锁首次分配内存时执行一次互斥锁初始化函数(mutex_init)即 可。后续的内存分配不需要执行这个初始化函数,因为从上次释放和调用析构之后,它已经处于所需的状态中了。 网管网www_bitscn_com

  Linux slab 分配器使用了这种思想和其他一些思想来构建一个在空间和时间上都具有高效性的内存分配器。

网管论坛bbs_bitsCN_com

  图 1 给出了 slab 结构的高层组织结构。在最高层是 cache_chain,这是一个 slab 缓存的链接列表。这对于 best-fit 算法非常有用,可以用来查找最适合所需要的分配大小的缓存(遍历列表)。cache_chain 的每个元素都是一个 kmem_cache 结构的引用(称为一个 cache)。它定义了一个要管理的给定大小的对象池。 网管网www.bitscn.com

中国网管联盟bitsCN.com

图  1. slab 分配器的主要结构 网管u家u.bitscn@com

  每个缓存都包含了一个 slabs 列表,这是一段连续的内存块(通常都是页面)。存在 3 种 slab:

网管bitscn_com

  slabs_full 网管网www.bitscn.com

  完全分配的 slab

网管论坛bbs_bitsCN_com

  slabs_partial

中国网管联盟bitsCN.com

  部分分配的 slab 网管联盟bitsCN_com

  slabs_empty 网管联盟bitsCN_com

  空 slab,或者没有对象被分配 网管下载dl.bitscn.com

  注意 slabs_empty 列表中的 slab 是进行回收(reaping)的主要备选对象。正是通过此过程,slab 所使用的内存被返回给操作系统供其他用户使用。

中国网管联盟bitsCN.com

  slab 列表中的每个 slab 都是一个连续的内存块(一个或多个连续页),它们被划分成一个个对象。这些对象是从特定缓存中进行分配和释放的基本元素。注意 slab 是 slab 分配器进行操作的最小分配单位,因此如果需要对 slab 进行扩展,这也就是所扩展的最小值。通常来说,每个 slab 被分配为多个对象。 网管bitscn_com

  由于对象是从 slab 中进行分配和释放的,因此单个 slab 可以在 slab 列表之间进行移动。例如,当一个 slab 中的所有对象都被使用完时,就从 slabs_partial 列表中移动到 slabs_full 列表中。当一个 slab 完全被分配并且有对象被释放后,就从 slabs_full 列表中移动到 slabs_partial 列表中。当所有对象都被释放之后,就从 slabs_partial 列表移动到 slabs_empty 列表中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值