了解 glibc malloc binning 实现
Understanding the glibc malloc binning implementation
最近我一直在研究 glibc malloc 实现的内部结构。但是,关于 bin 索引,我似乎无法理解一件事。因此,在 malloc_state 结构中,我们有以下声明,为简洁起见,格式略有不同:
struct malloc_state
{
/*
.
.
Some declarations
.
.
*/
/* Set if the fastbin chunks contain recently inserted free blocks. */
/* Note this is a bool but not all targets support atomics on booleans. */
int have_fastchunks;
/* 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];
/*
.
.
Some more declarations
.
.
*/
};
现在我的问题是关于此结构中 bins 数组的声明。 bins 数组声明如下:
mchunkptr bins[NBINS * 2 - 2];
根据我的理解,使用定义如下的 bin_at 宏获得指向 bin 的指针:
typedef struct malloc_chunk *mbinptr;
/* addressing -- note that bin_at(0) does not exist */
#define bin_at(m, i) \
(mbinptr) (((char *) &((m)->bins[((i) - 1) * 2])) \
- offsetof (struct malloc_chunk, fd))
现在具体来说,我的问题如下。为什么 bins 数组中保留的 bins 数量大约是原来的两倍?我知道有一个 bin 为调用 free 产生的未排序块保留,并且有 NBINS 数量的 bins 用于已经大小排序的空闲块。但是,我不明白剩余垃圾箱的用途。
我怀疑这背后是有原因的。但是,从源代码来看,这对我来说并不清楚。如果你们中的任何人有一些关于为什么这样做的指示或文档,那将不胜感激!
提前致谢!
由于 bins 是 doubly-linked 列表,每个 bin header 包含两个指针,而不是一个:第一个指针指向列表的头部,第二个指针指向尾部。这就是为什么指针的数量是容器数量的两倍。 (注意没有使用0号bin,所以bin数真的是NBINS - 1
。)
在 doubly-linked 列表实现中很常见,列表实际上是循环的; header 可以被视为 link 条目。这避免了在添加元素之前检查 bin 是否存在的必要性。 (在空容器中,第一个和最后一个都指向容器 header 本身。)但是,malloc_chunk
中的前向(fd
)和后向(bk
)指针不在块的开头。为了将bin数组中的这对指针当作一个chunk entry,需要将这对指针的地址反向偏移malloc_chunk
中fd
指针的偏移量。
图表可能会有所帮助。这是垃圾桶中有两个块的样子:
Bins Array Chunk 0 Chunk 1
+--> XXXXXXXXXX <-\ /--> +--------+ <-\ /--> +--------+ <-----+
| XXXXXXXXXX \ / | p_sz | \ / | p_sz | |
| XXXXXXXXXX \ / +--------+ \ / +--------+ |
| XXXXXXXXXX X | sz | X | sz | |
| +--------+ / \ +--------+ / \ +--------+ |
| | [2i-2] | -->/ \ | fd | -->/ \ | fd | ->+ |
| +--------+ \ +--------+ \ +--------+ | |
| | [2i-1] | -->+ \<- | bk | \<- | bk | | |
| +--------+ | +--------+ +--------+ | |
| | | |
| +----------------------------------------------+---+
| |
+<----------------------------------------------------------------+
XXX
s 显示允许指针一致的反向偏移量。
最近我一直在研究 glibc malloc 实现的内部结构。但是,关于 bin 索引,我似乎无法理解一件事。因此,在 malloc_state 结构中,我们有以下声明,为简洁起见,格式略有不同:
struct malloc_state
{
/*
.
.
Some declarations
.
.
*/
/* Set if the fastbin chunks contain recently inserted free blocks. */
/* Note this is a bool but not all targets support atomics on booleans. */
int have_fastchunks;
/* 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];
/*
.
.
Some more declarations
.
.
*/
};
现在我的问题是关于此结构中 bins 数组的声明。 bins 数组声明如下:
mchunkptr bins[NBINS * 2 - 2];
根据我的理解,使用定义如下的 bin_at 宏获得指向 bin 的指针:
typedef struct malloc_chunk *mbinptr;
/* addressing -- note that bin_at(0) does not exist */
#define bin_at(m, i) \
(mbinptr) (((char *) &((m)->bins[((i) - 1) * 2])) \
- offsetof (struct malloc_chunk, fd))
现在具体来说,我的问题如下。为什么 bins 数组中保留的 bins 数量大约是原来的两倍?我知道有一个 bin 为调用 free 产生的未排序块保留,并且有 NBINS 数量的 bins 用于已经大小排序的空闲块。但是,我不明白剩余垃圾箱的用途。
我怀疑这背后是有原因的。但是,从源代码来看,这对我来说并不清楚。如果你们中的任何人有一些关于为什么这样做的指示或文档,那将不胜感激!
提前致谢!
由于 bins 是 doubly-linked 列表,每个 bin header 包含两个指针,而不是一个:第一个指针指向列表的头部,第二个指针指向尾部。这就是为什么指针的数量是容器数量的两倍。 (注意没有使用0号bin,所以bin数真的是NBINS - 1
。)
在 doubly-linked 列表实现中很常见,列表实际上是循环的; header 可以被视为 link 条目。这避免了在添加元素之前检查 bin 是否存在的必要性。 (在空容器中,第一个和最后一个都指向容器 header 本身。)但是,malloc_chunk
中的前向(fd
)和后向(bk
)指针不在块的开头。为了将bin数组中的这对指针当作一个chunk entry,需要将这对指针的地址反向偏移malloc_chunk
中fd
指针的偏移量。
图表可能会有所帮助。这是垃圾桶中有两个块的样子:
Bins Array Chunk 0 Chunk 1
+--> XXXXXXXXXX <-\ /--> +--------+ <-\ /--> +--------+ <-----+
| XXXXXXXXXX \ / | p_sz | \ / | p_sz | |
| XXXXXXXXXX \ / +--------+ \ / +--------+ |
| XXXXXXXXXX X | sz | X | sz | |
| +--------+ / \ +--------+ / \ +--------+ |
| | [2i-2] | -->/ \ | fd | -->/ \ | fd | ->+ |
| +--------+ \ +--------+ \ +--------+ | |
| | [2i-1] | -->+ \<- | bk | \<- | bk | | |
| +--------+ | +--------+ +--------+ | |
| | | |
| +----------------------------------------------+---+
| |
+<----------------------------------------------------------------+
XXX
s 显示允许指针一致的反向偏移量。