【问题标题】:Understanding the glibc malloc binning implementation了解 glibc malloc 分箱实现
【发布时间】:2020-12-15 10:01:13
【问题描述】:

最近我一直在研究 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 的指针是使用定义如下的 bin_at 宏获得的:

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 数组中保留的 bin 数量大约是两倍?我知道有一个 bin 是为调用 free 产生的未排序的块保留的,并且有 NBINS 数量的 bin 用于已经大小排序的空闲块。但是,我不明白剩余垃圾箱的用途。

我怀疑这背后是有原因的。但是,从源代码来看,这对我来说并不清楚。如果你们中的任何人有一些关于为什么这样做的指示或文档,那将不胜感激!

提前谢谢你!

【问题讨论】:

    标签: c malloc glibc bins


    【解决方案1】:

    由于 bin 是双向链表,每个 bin 头包含两个指针,而不是一个:第一个指针指向链表的头部,第二个指针指向链尾。这就是为什么指针的数量是 bin 数量的两倍。 (注意没有使用bin号0,所以bin的数量真的是NBINS - 1。)

    在双向链表实现中很常见,列表实际上是循环的;标题可以看作是一个链接条目。这避免了在添加元素之前检查 bin 是否存在的必要性。 (在一个空的 bin 中,第一个和最后一个都指向 bin 标头本身。)但是,malloc_chunk 中的前向 (fd) 和后向 (bk) 指针不在块的开头。为了将bin数组中的一对指针当作一个chunk entry,这对指针的地址需要反向偏移malloc_chunkfd指针的偏移量。

    图表可能会有所帮助。下面是 bin 中有两个块时的样子:

         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   |   |   |
    |    +--------+    |         +--------+              +--------+   |   |
    |                  |                                              |   |
    |                  +----------------------------------------------+---+
    |                                                                 |
    +<----------------------------------------------------------------+
    

    XXXs 显示反向偏移量,使指针保持一致。

    【讨论】:

    • 感谢您的回复!
    • @HeapScholar:我添加了图表。希望对您有所帮助。
    • 这很有帮助。非常感谢您的精心回复!
    猜你喜欢
    • 2016-12-03
    • 2020-09-17
    • 1970-01-01
    • 2013-06-07
    • 2012-09-22
    • 2015-11-30
    • 2014-03-14
    • 2018-04-04
    • 1970-01-01
    相关资源
    最近更新 更多