分箱式内存管理

Unsorted bin

  Unsorted bin 可以看作是 small bins 和 large bins 的 cache,只有一个 unsorted bin,以双向链表管理空闲 chunk,空闲 chunk 不排序,所有的 chunk 在回收时都要先放到 unsorted bin 中,分配时,如果在 unsorted bin 中没有合适的 chunk,就会把 unsorted bin 中的所有 chunk 分别加入到所属的 bin 中,然后再在 bin 中分配合适的 chunk。Bins 数组中的元素 bin[1]用于存储 unsorted bin 的 chunk 链表头。

/* The otherwise unindexable 1-bin is used to hold unsorted chunks. */
#define unsorted_chunks(M) (bin_at(M, 1)) /* Conveniently, the unsorted bin can be used as dummy top on first call */
#define initial_top(M) (unsorted_chunks(M))
  • unsorted_chunks(M):把 bin[1]设置为 unsorted bin 的 chunk 链表头。
  • initial_top(M):对 top chunk 的初始化,也暂时把 top chunk 初始化为 unsort chunk,仅仅是初始化一个值而已,这个 chunk 的内容肯定不能用于 top chunk 来分配内存,主要原因是 top chunk 不属于任何 bin,但 ptmalloc 中的一些 check 代码,可能需要 top chunk 属于一个合法的 bin。

Fast bins

  Fast bins 主要是用于提高小内存的分配效率,默认情况下,对于 SIZE_SZ 为 4B 的平台,小于 64B 的 chunk 分配请求,对于 SIZE_SZ 为 8B 的平台,小于 128B 的 chunk 分配请求,首先会查找 fast bins 中是否有所需大小的 chunk 存在(精确匹配),如果存在,就直接回。

  Fast bins 可以看着是 small bins 的一小部分 cache,默认情况下,fast bins 只 cache 了 small bins 的前 7 个大小的空闲 chunk,也就是说,对于 SIZE_SZ 为 4B 的平台,fast bins 有 7 个 chunk 空闲链表(bin),每个 bin 的 chunk 大小依次为 16B,24B,32B,40B,48B,56B,64B;对于 SIZE_SZ 为 8B 的平台,fast bins 有 7 个 chunk 空闲链表(bin),每个 bin 的 chunk 大小依次为 32B,48B,64B,80B,96B,112B,128B。

  • Fast bins 可以看着是 LIFO 的栈,使用单向链表实现。
typedef struct malloc_chunk* mfastbinptr;
#define fastbin(ar_ptr, idx) ((ar_ptr)->fastbinsY[idx]) /* offset 2 to use otherwise unindexable first 2 bins */
#define fastbin_index(sz) \
((((unsigned int)(sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2) /* The maximum fastbin request size we support */
#define MAX_FAST_SIZE (80 * SIZE_SZ / 4)
#define NFASTBINS (fastbin_index(request2size(MAX_FAST_SIZE))+1) #define FASTBIN_CONSOLIDATION_THRESHOLD (65536UL) #ifndef DEFAULT_MXFAST
#define DEFAULT_MXFAST (64 * SIZE_SZ / 4)
#endif #define set_max_fast(s) \
global_max_fast = (((s) == 0) \
? SMALLBIN_WIDTH: ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK))
#define get_max_fast() global_max_fast
  • fastbin(ar_ptr, idx):根据 fast bin 的 index,获得 fast bin 的地址。Fast bins 的数字定义在 malloc_state 中。
  • fastbin_index(sz):于获得 fast bin 在 fast bins 数组中的 index,由于 bin[0]和 bin[1]中的chunk不存在,所以需要减2,对于SIZE_SZ为4B的平台,将sz除以8减2得到fast bin index,对于 SIZE_SZ 为 8B 的平台,将 sz 除以 16 减去 2 得到 fast bin index。
  • MAX_FAST_SIZE:根据 SIZE_SZ 的不同大小,定义 MAX_FAST_SIZE 为 80B 或是 160B。
  • NFASTBINS:fast bins 数组的大小 NFASTBINS 为 10。
  • FASTBIN_CONSOLIDATION_THRESHOLD:FASTBIN_CONSOLIDATION_THRESHOLD 为 64k,当每次释放的 chunk 与该 chunk 相邻的空闲 chunk 合并后的大小大于 64k 时,就认为内存碎片可能比较多了,就需要把 fast bins 中的所有 chunk 都进行合并,以减少内存碎片对系统的影响。
  • DEFAULT_MXFAST:定义了默认的 fast bins 中最大的 chunk 大小,对于 SIZE_SZ 为 4B 的平台,最大 chunk 为 64B,对于 SIZE_SZ 为 8B 的平台,最大 chunk 为 128B。
  • set_max_fast(s):ptmalloc 默认情况将全局变量 global_max_fast 设置为 DEFAULT_MXFAST,也就是设置 fast bins 中 chunk 的最大值。
  • get_max_fast():获得这个全局变量 global_max_fast的值。

核心结构体分析

  每个分配区是 struct malloc_state 的一个实例,ptmalloc 使用 malloc_state 来管理分配区,而参数管理使用 struct malloc_par,全局拥有一个唯一的 malloc_par 实例。

malloc_state

struct malloc_state {
/* Serialize access. */
mutex_t mutex; /* Flags (formerly in max_fast). */
int flags;
#if THREAD_STATS
/* Statistics for locking. Only used if THREAD_STATS is defined. */
long stat_lock_direct, stat_lock_loop, stat_lock_wait;
#endif /* Fastbins */
mfastbinptr fastbinsY[NFASTBINS]; /* Base of the topmost chunk -- not otherwise kept in a bin */
mchunkptr top; /* The remainder from the most recent split of a small request */
mchunkptr last_remainder; /* Normal bins packed as described above */
mchunkptr bins[NBINS * 2 - 2]; /* Bitmap of bins */
unsigned int binmap[BINMAPSIZE]; /* Linked list */
struct malloc_state *next; #ifdef PER_THREAD
/* Linked list for free arenas. */
struct malloc_state *next_free;
#endif /* Memory allocated from the system in this arena. */
INTERNAL_SIZE_T system_mem;
INTERNAL_SIZE_T max_system_mem;
};
  • Mutex:用于串行化访问分配区,当有多个线程访问同一个分配区时,第一个获得这个 mutex 的线程将使用该分配区分配内存,分配完成后,释放该分配区的 mutex,以便其它线程使用该分配区。
  • Flags:记录了分配区的一些标志,bit0 用于标识分配区是否包含至少一个 fast bin chunk,bit1 用于标识分配区是否能返回连续的虚拟地址空间。
  • fastbinsY:拥有 10(NFASTBINS)个元素的数组,用于存放每个 fast chunk 链表头指针,所以 fast bins 最多包含 10 个 fast chunk 的单向链表。
  • top:一个 chunk 指针,指向分配区的 top chunk。
  • last_remainder:是一个 chunk 指针,分配区上次分配 small chunk 时,从一个 chunk 中分裂出一个 small chunk 返回给用户,分裂后的剩余部分形成一个 chunk,last_remainder 就是指向的这个 chunk。
  • binmap:一个 int 数组,ptmalloc 用一个 bit 来标识该 bit 对应的 bin 中是否包含空闲 chunk。
#define FASTCHUNKS_BIT (1U)
#define have_fastchunks(M) (((M)->flags & FASTCHUNKS_BIT) == 0)
#ifdef ATOMIC_FASTBINS
#define clear_fastchunks(M) catomic_or (&(M)->flags, FASTCHUNKS_BIT)
#define set_fastchunks(M) catomic_and (&(M)->flags, ~FASTCHUNKS_BIT)
#else
#define clear_fastchunks(M) ((M)->flags |= FASTCHUNKS_BIT)
#define set_fastchunks(M) ((M)->flags &= ~FASTCHUNKS_BIT)
#endif
  • have_fastchunks(M):如果返回值为 1,表示分配区有 fast bin,如果返回值为 0,表示没有 fast bin。
  • clear_fastchunks(M):将 bit0 标志位置 1,及无 fast bin。
  • set_fastchunks(M):将 bit0 标志位置 0,及有 fast bin。
  • 初始化完成后的 malloc_state 实例中,flags 值为 0,表示该分配区中有 fast chunk,但实际上没有,试图从 fast bins 中分配chunk 都会返回 NULL,在第一次调用函数 malloc_consolidate()对 fast bins 进行 chunk 合并时,如果 max_fast 大于 0,会调用 clear_fastchunks 宏,标志该分配区中已经没有 fast chunk,因为函数 malloc_consolidate()会合并所有的 fast bins 中的 chunk。clear_fastchunks 宏只会在函数 malloc_consolidate()中调用。当有 fast chunk 加入 fast bins 时,就是调用 set_fastchunks 宏标

    识分配区的 fast bins 中存在 fast chunk。
#define NONCONTIGUOUS_BIT (2U)
#define contiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) == 0)
#define noncontiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) != 0)
#define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT)
#define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT)
  • contiguous(M):返回值为 1,表示 MORCORE 返回连续虚拟地址空间;返回值为 0,表示 MORCORE 返回非连续虚拟地址空间。
  • noncontiguous(M):返回值为 1,表示 MORCORE 返回非连续虚拟地址空间;返回值为 0,表示 MORCORE 返回连续虚拟地址空间。
  • set_noncontiguous(M):将 bit1 标志位置 1,表示 MORCORE 返回非连续虚拟地址空间。
  • set_contiguous(M):将 bit1 标志位置 0,表示 MORCORE 返回连续虚拟地址空间。

内容来源

《Glibc内存管理》

《Glibc内存管理》笔记DAY5的更多相关文章

  1. 《Glibc内存管理》笔记DAY4

    目录 分箱式内存管理 Small bins Large bins 内容来源 分箱式内存管理   对于空闲的 chunk,ptmalloc 采用分箱式内存管理方式,根据空闲 chunk 的大小和处于的状 ...

  2. 《Glibc内存管理》笔记DAY3

    目录 边界标记法 内容来源 边界标记法 /* conversion from malloc headers to user pointers, and back */ #define chunk2me ...

  3. 《Glibc内存管理》笔记DAY2

    目录 Ptmalloc内存管理设计 Main_arena 与 non_main_arena chunk 的组织 空闲 chunk 容器 sbrk 与 mmap 内存分配概述 内存回收概述 边界标记法 ...

  4. 《Glibc内存管理》笔记DAY1

    目录 x86_64栈和mmap固定映射地址 内存的延迟分配 内核数据结构 mm_struct Heap 操作相关函数 Mmap 映射区域操作相关函数 内容来源 x86_64栈和mmap固定映射地址   ...

  5. 2万字|30张图带你领略glibc内存管理精髓(因为OOM导致了上千万损失)

    前言 大家好,我是雨乐. 5年前,在上家公司的时候,因为进程OOM造成了上千万的损失,当时用了一个月的时间来分析glibc源码,最终将问题彻底解决. 最近在逛知乎的时候,发现不少人有对malloc/f ...

  6. 读书摘要观后感与总结:《Glibc内存管理:ptmalloc2源代码分析》

    更新中 在Linux平台下做漏洞利用的时候,针对于Heap部分总是有些不求甚解,下面开个博文来记录下<Glibc内存管理:ptmalloc2源代码分析>这本书的读后感和收获,一些简单的点将 ...

  7. glibc内存管理那些事儿

    本文转载自glibc内存管理那些事儿 Linux内存空间简介 32位Linux平台下进程虚拟地址空间分布如下图: 进程虚拟地址空间分布 图中,0xC0000000开始的最高1G空间是内核地址空间,剩下 ...

  8. 黑马程序员_ Objective-c 内存管理笔记

    引用计数器 当一个对象被创建出来,就要分配给内存这个对象,当不用这个对象的时候,就要及时的回收,为了可以明确知道对象有没有被使用,就要用引用计数器来体现,只要计数器不为0,表明对象被使用中. 1.方法 ...

  9. Java内存管理笔记

    java内存管理机制 在java中,内存管理由JVM完全负责,java中的"垃圾回收器"负责自动回收无用对象占据的内存资源,这样可以大大减少程序猿在内存管理上花费的时间,可以更集中 ...

随机推荐

  1. EWA不能及时通过邮件接收

    1. 确保EWA已经配置成功.可以通过SW_workcenter查看 2.确保EWA的邮箱设置成功 3. 检查EWAreport产生的时间 卫星系统:SDCCN 在tab"done" ...

  2. BPM FlowPortal 开发环境及发布环境的配置

    开启开发模式 开发时应设置防缓存和调试信息输出. 开发后发布 开发完成后正式使用时,除了对以上各项做相反设置外,还需设置web.config中的JSVersion,使每个用户都能自动下载最新版的js文 ...

  3. mysql数据库的多实例与主从同步。

    1.MySQL的多实例: 多实例的特点:能够有效地利用服务器的资源,节约服务器的资源 MySQL多实例的配置有两种,第一是使用一个配置文件,这种方法不推荐使用,容易出错:第二种是用多个配置文件,这种方 ...

  4. [dev][ipsec] 基于路由的VPrivateN

    VPrivateN的配置分两个模式 1. 基于策略的VPrivateN ( policy based) 2. 基于路由的VPrivateN (route based) 以strongswan为例, 在 ...

  5. WebApi增加Oauth2认证

    前期搭建可看这篇博文:https://www.cnblogs.com/lnice/p/6857203.html,此博文是在本篇博文实践才产生的,在实践中,也产生了几个问题,希望能够共同交流,一起进步. ...

  6. Python语言程序设计:Lab5

    Programming Create a Class Student which should have the following information:Parameters passed to ...

  7. FM系列

    在计算广告中,CTR是非常重要的一环.对于特征组合来说,业界通用的做法主要有两大类:FM系列和Tree系列.这里我们来介绍一下FM系列. 在传统的线性模型中,每个特征都是独立的,如果需要考虑特征与特征 ...

  8. G1垃圾收集器堆内存划分与角色分派【纯理论】

    接着上一次[https://www.cnblogs.com/webor2006/p/11123522.html]G1学习继续开启理论之旅.. G1的设计规划是要替换掉CMS[理想化的] G1在某些方面 ...

  9. unable to access 'https://github.com/shixianqing/img.git/': SSL connect error 解决办法

    解决在linux环境下,git clone 项目,走https协议时,报SSL connect error 错误 升级nss yum update -y nss curl libcurl

  10. 第七届蓝桥杯C/C++程序设计本科B组决赛 ——机器人塔(程序大题)

    机器人塔 X星球的机器人表演拉拉队有两种服装,A和B.他们这次表演的是搭机器人塔. 类似: A B B A B A A A B B B B B A BA B A B B A 队内的组塔规则是: A 只 ...