一:

slab是为了解决内部碎片提出的,还是外部碎片?

为了解决内部碎片。

内部碎片的产生:因为所有的内存分配必须起始于可被 4、8 或 16 整除(视处理器体系结构而定)的地址或者因为MMU的分页机制的限制,决定内存分配算法仅能把预定大小的内存块分配给客户。假设当某个客户请求一个 43 字节的内存块时,因为没有适合大小的内存,所以它可能会获得 44字节、48字节等稍大一点的字节,因此由所需大小四舍五入而产生的多余空间就叫内部碎片。

外部碎片的产生: 频繁的分配与回收物理页面会导致大量的、连续且小的页面块夹杂在已分配的页面中间,就会产生外部碎片。假设有一块一共有100个单位的连续空闲内存空间,范围是0~99。如果你从中申请一块内存,如10个单位,那么申请出来的内存块就为0~9区间。这时候你继续申请一块内存,比如说5个单位大,第二块得到的内存块就应该为10~14区间。如果你把第一块内存块释放,然后再申请一块大于10个单位的内存块,比如说20个单位。因为刚被释放的内存块不能满足新的请求,所以只能从15开始分配出20个单位的内存块。现在整个内存空间的状态是0~9空闲,10~14被占用,15~24被占用,25~99空闲。其中0~9就是一个内存碎片了。如果10~14一直被占用,而以后申请的空间都大于10个单位,那么0~9就永远用不上了,变成外部碎片。

二:

slab算法的核心思想是什么?

slab的核心思想是以对象的观点来管理内存。

内核对其对象的使用具有以下特殊性:

  1. 内核使用的对象种类繁多,应该采用一种统一的高效管理方法。
  2. 内核对某些对象(如
    task_struct)的使用是非常频繁的,所以用户进程堆管理常用的基于搜索的分配算法比如First-Fit(在堆中搜索到的第一个满足请求的内存块)和
    Best-Fit(使用堆中满足请求的最合适的内存块)并不直接适用,而应该采用某种缓冲区的机制。
  3. 内核对象中相当一部分成员需要某些特殊的初始化(例如队列头部)而并非简单地清成全 0。如果能充分重用已被释放的对象使得下次分配时无需初始化,那么可以提高内核的运行效率。
  4. 分配器对内核对象缓冲区的组织和管理必须充分考虑对硬件高速缓存的影响。
  5. 随着共享内存的多处理器系统的普及,多处理器同时分配某种类型对象的现象时常发生,因此分配器应该尽量避免处理器间同步的开销,应采用某种 Lock-Free 的算法。

所以,这就需要slab机制以对象的观点来解决小内存问题。

三:有关slab的着色问题

着色与硬件cache有关,这就牵扯到cache和主存的工作结构:

  1. 全相连

    • 任一主存块能映射到任意缓存行(主存块的大小等于缓存行的大小。
    • 优点:灵活,不易产生冲突
    • 缺点:比较电路难于实现,且效率低,速度慢
  2. 直接映射
    • 某一主存块只能映射到特定的缓存行
    • 优点:硬件简单,成本低
    • 缺点:容易产生冲突,易产生缓存“颠簸”,不能有效利用cache空间
  3. 组相联
    • 组间直接映射,组内全相联映射
    • 优点:结合上面两种的优点
      • 因为组内行数较少,比较器容易实现
      • 组内又有灵活性,冲突大大减小

由上可知,slab着色对于直接映射和组相连映射的工作结构效率帮助较大,而全项链结构本身冲突就比较小,那么着色的帮助是很小的。在全相连工作结构中,使用着色无疑是一个巨大的内存浪费。

slab算法的缺点

随着大规模多处理器系统和NUMA系统的广泛应用,slab分配器逐渐暴露出自身严重的不足:

  1. 较多复杂的队列管理。在slab分配器中存在众多的队列,例如针对处理器的本地缓存队列,slab中空闲队列,每个slab处于一个特定状态的队列之中。所以,管理太费劲了。
  2. slab管理数据和队列的存储开销比较大。每个slab需要一个struct
    slab数据结构和一个管理者kmem_bufctl_t型的数组。当对象体积较小时,该数组将造成较大的开销(比如对象大小为32字节时,将浪费1/8空间)。为了使得对象在硬件告诉缓存中对齐和使用着色策略,还必须浪费额外的内存。同时,缓冲区针对节点和处理器的队列也会浪费不少内存。测试表明在一个1000节点/处理器的大规模NUMA系统中,数GB内存被用来维护队列和对象引用。
  3. 缓冲区回收比较复杂。
  4. 对NUMA的支持非常复杂。slab对NUMA的支持基于物理页框分配器,无法细粒度的使用对象,因此不能保证处理器级的缓存来自同一节点(这个我暂时不太懂)。
  5. 冗余的partial队列。slab分配器针对每个节点都有一个partial队列,随着时间流逝,将有大量的partial slab产生,不利于内存的合理使用。
  6. 性能调优比较困难。针对每个slab可以调整的参数比较复杂,而且分配处理器本地缓存时,不得不使用自旋锁。
  7. 调试功能比较难于使用。

为了解决以上slab分配器的不足,引入新的解决方案,slub分配器。slub分配器的特点是简化设计理念,同时保留slab分配器的基本思想:每个缓冲区有多个slab组成,每个slab包含固定数目的对象。slub分配器简化了kmem_cache,slab等相关的管理结构,摈弃了slab分配器中的众多队列概念,并针对多处理器、NUMA系统进行优化,从而提高了性能和可扩展性并降低了内存的浪费。并且,为了保证内核其他模块能无缝迁移到slub分配器,API接口函数与slab保持一致。

缺点简单说就是:

  1. 缓存队列管理复杂;
  2. 管理数据存储开销大;
  3. 对NUMA支持复杂;
  4. 调试调优困难;
  5. 摒弃了效果不太明显的slab着色机制;

过些天就开始剖析slub分配器,不过由于有slab的基础,那个已经是小菜了。

slab机制总结篇的更多相关文章

  1. 通过扩展改善ASP.NET MVC的验证机制[实现篇]

    原文:通过扩展改善ASP.NET MVC的验证机制[实现篇] 在<使用篇>中我们谈到扩展的验证编程方式,并且演示了本解决方案的三大特性:消息提供机制的分离.多语言的支持和多验证规则的支持, ...

  2. 通过扩展改善ASP.NET MVC的验证机制[使用篇]

    原文:通过扩展改善ASP.NET MVC的验证机制[使用篇] ASP.NET MVC提供一种基于元数据的验证方式是我们可以将相应的验证特性应用到作为Model实体的类型或者属性/字段上,但是这依然具有 ...

  3. slab机制

    1.内部碎片和外部碎片 外部碎片 什么是外部碎片呢?我们通过一个图来解释: 假设这是一段连续的页框,阴影部分表示已经被使用的页框,现在需要申请一个连续的5个页框.这个时候,在这段内存上不能找到连续的5 ...

  4. 详解slab机制

    转 详解slab机制 2015年01月15日 16:34:47 cosmoslhf 阅读数:12657   http://blog.csdn.net/u010246947/article/detail ...

  5. Nginx之共享内存与slab机制

    1. 共享内存 在 Nginx 里,一块完整的共享内存以结构体 ngx_shm_zone_t 来封装,如下: typedef struct ngx_shm_zone_s ngx_shm_zone_t; ...

  6. Android 异步消息处理机制终结篇 :深入理解 Looper、Handler、Message、MessageQueue四者关系

    版权声明:本文出自汪磊的博客,转载请务必注明出处. 一.概述 我们知道更新UI操作我们需要在UI线程中操作,如果在子线程中更新UI会发生异常可能导致崩溃,但是在UI线程中进行耗时操作又会导致ANR,这 ...

  7. .Net Discovery 系列之七--深入理解.Net垃圾收集机制(拾贝篇)

    关于.Net垃圾收集器(Garbage Collection),Aicken已经在“.Net Discovery 系列”文章中有2篇的涉及,这一篇文章是对上2篇文章的补充,关于“.Net Discov ...

  8. JavaScript消息机制入门篇

    JavaScript这个语言本身就是建立在一种消息机制上的,所以它很容易处理异步回调和各种事件.这个概念与普通的编程语言基础是不同的,所以让很多刚接触JavaScript的人摸不着头脑.JavaScr ...

  9. 漫谈JVM之类加载机制(篇一)

    前言 最近在看一本书,发现代码里用到了Thread.currentThread().getContextClassLoader(),为什么类加载器还与线程有关系呢,为什么不直接使用ClassLoade ...

随机推荐

  1. Python:virtualenv介绍

    virtualenv 在开发Python应用程序的时候,系统安装的Python3只有一个版本:3.4.所有第三方的包都会被pip安装到Python3的site-packages目录下. 如果我们要同时 ...

  2. oracle 创建视图、修改视图、删除视图、利用视图操作基本表

    转:http://blog.sina.com.cn/s/blog_6b58d2fa0100rgvw.html 1.使用create or replace view命令创建视图 语法格式: create ...

  3. 搭建Mac OS X下cocos2d-x的Android开发环境

    版本 Cocos2d-x: cocos2d-2.1beta3-x-2.1.1 OS X: 10.8 Android ADT Bundle: v21.1.0 Android NDK: android-n ...

  4. JAVA 对象序列化——Serializable(转)

    文章出自:http://www.cnblogs.com/chenfei0801/archive/2013/04/05/3001149.html Java的对象序列化是指将那些实现了Serializab ...

  5. ES6 随记(3.3)-- 数组的拓展

    上一章请见: 1. ES6 随记(1)-- let 与 const 2. ES6 随记(2)-- 解构赋值 3. ES6 随记(3.1)-- 字符串的拓展 4. ES6 随记(3.2)-- 正则的拓展 ...

  6. Hbase:简单介绍一下Hbase表的结构

    HBase 是一个NoSQL数据库,用于处理海量数据,可以支持10亿行百万列的大表,下面我就和大家分享一下数据是如何存放在HBase表中的 为了更好的理解HBase表的思路,先回顾一下关系数据库中表的 ...

  7. MyBatis正在爬的坑

    换了份工作,开始接触Mybatis,开一篇文章记录一下自己遇到的坑 2018-06-20 今天遇到了一个问题,编好的sql语句在数据库可以执行但是写到程序里边就GG,什么问题呢?一直纠结在程序哪里写错 ...

  8. Cisco、HUAWEI、H3c、Firewall等设备配置snmp

    配置HUAWEI交换机S1720.S2700.S5700.S6720等型号设备的snmp v3配置 注:此配置来源自官方配置文档 操作步骤 配置交换机的接口IP地址,使其和网管站之间路由可达 (图1) ...

  9. 判断iframe页面是否是顶层页面

    if (self!=top) {  window.parent.location.reload();}

  10. java中TreeMap集合的常用方法

    实现Map集合的方法这里就不在讲了 https://www.cnblogs.com/xiaostudy/p/9510763.html public Map.Entry<K,V> ceili ...