《Glibc内存管理》笔记DAY5
分箱式内存管理
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的更多相关文章
- 《Glibc内存管理》笔记DAY4
目录 分箱式内存管理 Small bins Large bins 内容来源 分箱式内存管理 对于空闲的 chunk,ptmalloc 采用分箱式内存管理方式,根据空闲 chunk 的大小和处于的状 ...
- 《Glibc内存管理》笔记DAY3
目录 边界标记法 内容来源 边界标记法 /* conversion from malloc headers to user pointers, and back */ #define chunk2me ...
- 《Glibc内存管理》笔记DAY2
目录 Ptmalloc内存管理设计 Main_arena 与 non_main_arena chunk 的组织 空闲 chunk 容器 sbrk 与 mmap 内存分配概述 内存回收概述 边界标记法 ...
- 《Glibc内存管理》笔记DAY1
目录 x86_64栈和mmap固定映射地址 内存的延迟分配 内核数据结构 mm_struct Heap 操作相关函数 Mmap 映射区域操作相关函数 内容来源 x86_64栈和mmap固定映射地址 ...
- 2万字|30张图带你领略glibc内存管理精髓(因为OOM导致了上千万损失)
前言 大家好,我是雨乐. 5年前,在上家公司的时候,因为进程OOM造成了上千万的损失,当时用了一个月的时间来分析glibc源码,最终将问题彻底解决. 最近在逛知乎的时候,发现不少人有对malloc/f ...
- 读书摘要观后感与总结:《Glibc内存管理:ptmalloc2源代码分析》
更新中 在Linux平台下做漏洞利用的时候,针对于Heap部分总是有些不求甚解,下面开个博文来记录下<Glibc内存管理:ptmalloc2源代码分析>这本书的读后感和收获,一些简单的点将 ...
- glibc内存管理那些事儿
本文转载自glibc内存管理那些事儿 Linux内存空间简介 32位Linux平台下进程虚拟地址空间分布如下图: 进程虚拟地址空间分布 图中,0xC0000000开始的最高1G空间是内核地址空间,剩下 ...
- 黑马程序员_ Objective-c 内存管理笔记
引用计数器 当一个对象被创建出来,就要分配给内存这个对象,当不用这个对象的时候,就要及时的回收,为了可以明确知道对象有没有被使用,就要用引用计数器来体现,只要计数器不为0,表明对象被使用中. 1.方法 ...
- Java内存管理笔记
java内存管理机制 在java中,内存管理由JVM完全负责,java中的"垃圾回收器"负责自动回收无用对象占据的内存资源,这样可以大大减少程序猿在内存管理上花费的时间,可以更集中 ...
随机推荐
- 在浏览器输入URL回车后发生了什么?
本文由 简悦 SimpRead 转码, 原文地址 https://4ark.me/post/b6c7c0a2.html 这个问题已经是老生常谈了,更是经常被作为面试的压轴题出现,网上也有很多文章,但最 ...
- 学习到目前,自己封装的db类和pdo类
DB封装类 <?php class DBDA { public $host = "localhost"; public $uid = "root"; pu ...
- S5PV210 启动流程
S3C6410启动流程 首先,看一下S3C6410启动流程 ① iROM supports initial boot up : initialize system clock, D-TCM, devi ...
- IO模型之NIO代码及其实践详解
一.简介 NIO我们一般认为是New I/O(也是官方的叫法),因为它是相对于老的I/O类库新增的( JDK 1.4中的java.nio.*包中引入新的Java I/O库).但现在都称之为Non-bl ...
- 前台.cshtml得到session值方法
方法一 <script> var s="@Session["visitor_name"]"; if(s=="")//解决报错问题 ...
- maya 在 pymel 中运行 mel
maya 在 pymel 中运行 mel 前言 maya mel 自身定义了很多有用的方法,当我们用 pymel 开发的时候,不想重新写一遍 mel 已经有的功能,那么就可以在 pymel 中运行 m ...
- Spring源码窥探之:Spring AOP初步
AOP(Aspect Oriented Programming):即我们常说的面向切面编程. 什么是AOP?AOP是在我们原来写的代码的基础上,进行一定的包装,比如在方法执行前.方法返回后.方法抛出异 ...
- JS转换HTML转义符 [转]
最近有个需求,就是后台系统编辑文章内容存到后台,前端这边获取到是转义后的字符串,如果直接将转义后的内容写在页面上,html标签不会被解析.网上找到觉得不错的功能函数,这里记录一下 //去掉html标签 ...
- MyBatsi学习
深入浅出Mybatis系列(一)---Mybatis入门 深入浅出Mybatis系列(二)---配置简介(mybatis源码篇) 深入浅出Mybatis系列(三)---配置详解之properties与 ...
- Django REST framework+Vue 打造生鲜电商项目(笔记十)
(from:https://www.cnblogs.com/derek1184405959/p/8877643.html 有修改) 十三.首页.商品数量.缓存和限速功能开发 首先把pycharm环境 ...