5.2.3
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
链表头。
/*
Unsorted chunks
All remainders from chunk splits, as well as all returned chunks,
are first placed in the "unsorted" bin. They are then placed
in regular bins after malloc gives them ONE chance to be used before
binning. So, basically, the unsorted_chunks list acts as a queue,
with chunks being placed on it in free (and malloc_consolidate),
and taken off (to be either used or placed in bins) in malloc.
The NON_MAIN_ARENA flag is never set for unsorted chunks, so it
does not have to be taken into account in size comparisons.
*/
/* The otherwise unindexable 1-bin is used to hold unsorted chunks. */
#define unsorted_chunks(M) (bin_at(M, 1))
/*
Top
The top-most available chunk (i.e., the one bordering the end of
available memory) is treated specially. It is never included in
any bin, is used only if no other chunk is available, and is
released back to the system if it is very large (see
M_TRIM_THRESHOLD). Because top initially
points to its own bin with initial zero size, thus forcing
extension on the first malloc request, we avoid having any special
code in malloc to check whether it even exists yet. But we still
need to do so when getting memory from system, so we make
initial_top treat the bin as a legal but unusable chunk during the
interval between initialization and the first call to
sYSMALLOc. (This is somewhat delicate, since it relies on
the 2 preceding words to be zero during this interval as well.)
*/
/* Conveniently, the unsorted bin can be used as dummy top on first call */
#define initial_top(M) (unsorted_chunks(M))
上面的宏的定义比较明显,把
bin[1]
设置为
unsorted
bin
的
chunk
链表头,对
top chunk
的初始化,也暂时把
top chunk
初始化为
unsort chunk
,仅仅是初始化一个值而已,这个
chunk
的内容肯定不能用于
top chunk
来分配内存,主要原因是
top chunk
不属于任何
bin
,但
ptmalloc
中的一些
check
代码,可能需要
top chunk
属于一个合法的
bin
。
5.2.4
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
。以
32
为系统为例,分配的内存大小与
chunk
大小和
fast bins
的对应关系如下表所示:
Fast bins
可以看着是
LIFO
的栈,使用单向链表实现。
/*
Fastbins
An array of lists holding recently freed small chunks. Fastbins
are not doubly linked. It is faster to single-link them, and
since chunks are never removed from the middles of these lists,
double linking is not necessary. Also, unlike regular bins, they
are not even processed in FIFO order (they use faster LIFO) since
ordering doesn't much matter in the transient contexts in which
fastbins are normally used.
Chunks in fastbins keep their inuse bit set, so they cannot
be consolidated with other free chunks. malloc_consolidate
releases all chunks in fastbins and consolidates them with
other free chunks.
*/
typedef struct malloc_chunk* mfastbinptr;
#define fastbin(ar_ptr, idx) ((ar_ptr)->fastbinsY[idx])
根据
fast bin
的
index
,获得
fast bin
的地址。
Fast bins
的数字定义在
malloc_state
中,
5.3
节会做详细介绍。
/* offset 2 to use otherwise unindexable first 2 bins */
#define fastbin_index(sz) \
((((unsigned int)(sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2)
宏
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
。
/* The maximum fastbin request size we support */
#define MAX_FAST_SIZE (80 * SIZE_SZ / 4)
#define NFASTBINS (fastbin_index(request2size(MAX_FAST_SIZE))+1)
/*
FASTBIN_CONSOLIDATION_THRESHOLD is the size of a chunk in free()
that triggers automatic consolidation of possibly-surrounding
fastbin chunks. This is a heuristic, so the exact value should not
matter too much. It is defined at half the default trim threshold as a
compromise heuristic to only attempt consolidation if it is likely
to lead to trimming. However, it is not dynamically tunable, since
consolidation reduces fragmentation surrounding large chunks even
if trimming is not used.
*/
#define FASTBIN_CONSOLIDATION_THRESHOLD (65536UL)
根据SIZE_SZ
的
不同大小,
定义
MAX_FAST_SIZE
为
80B
或是
160B
,
fast bins
数组的大小
NFASTBINS
为
10
,
FASTBIN_CONSOLIDATION_THRESHOLD
为
64k
,当每次释放的
chunk
与该
chunk
相邻的空闲
chunk
合并后的大小大于
64k
时,就认为内存碎片可能比较多了,就需要把
fast bins
中的所有
chunk
都进行合并,以减少内存碎片对系统的影响。
#ifndef DEFAULT_MXFAST
#define DEFAULT_MXFAST (64 * SIZE_SZ / 4)
#endif
/*
Set value of max_fast.
Use impossibly small value if 0.
Precondition: there are no existing fastbin chunks.
Setting the value clears fastchunk bit but preserves noncontiguous bit.
*/
#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
上面的宏
DEFAULT_MXFAST
定义了默认的
fast
bins
中最大的
chunk
大小,对于
SIZE_SZ
为
4B
的平台,最大
chunk
为
64B
,对于
SIZE_SZ
为
8B
的平台,最大
chunk
为
128B
。
ptmalloc
默认情况下调用
set_max_fast
(s)
将全局变量
global_max_fast
设置为
DEFAULT_MXFAST
,也就是设置
fast bins
中
chunk
的最大值,
get_max_fast
()
用于获得这个全局变量
global_max_fast
的值。
分享到:
相关推荐
NULL 博文链接:https://mqzhuang.iteye.com/blog/1064966
Glibc内存管理 Ptmalloc2 源代码分析
glibc内存管理ptmalloc源代码分析-电子资料-高清PDF版-pdf打印版
简介133.2.2内存管理的设计假设 143.2.3内存管理数据结构概述 143.2.4内存分配概述 193.2.5内存回收概述 213.2.6配置选项概述 2
淘宝网的研发人员写的文档,对了解GNU C的内存分配机制有很大的帮助!
该文档详细分析了c库中的内存管理细节,可广大程序员做参考。
简介133.2.2内存管理的设计假设 143.2.3内存管理数据结构概述 143.2.4内存分配概述 193.2.5内存回收概述 213.2.6配置选项概述 2
清晰版,对内存分析,程序设计非常有帮助。适合进阶的。
5. 源代码分析 5.1 边界标记法 5.2 分箱式内存管理 5.2.1 Small bins 5.2.2 Large bins 5.2.3 Unsorted bin 5.2.4 Fast bins 5.3 核心结构体分析 5.3.1 malloc_state 5.3.2 Malloc_par 5.3.3 分配区的初始...
glibc内存管理ptmalloc源代码分析.pdf
源代码分析 glibc的ptmalloc 分析
glibc内存管理ptmalloc源代码分析4.pdf
学习自《glibc内存管理ptmalloc源代码分析》庄明强 著 部分资料参考自互联网 chunk 描述: 当用户通过malloc等函数申请空间时,实际上是从堆中分配内存 目前 Linux 标准发行版中使用的是 glibc 中的堆分配器:...