• 堆内存管理


    前言:

      最近刚学堆,特写此文巩固一下知识(水平有限,本文可能有错误,望读者留心)。

    堆的结构:

      在Linux中,堆是使用glibc的ptmalloc2的分配方式,而malloc本质上都是通过brk或mmap实现的。通过brk分配的堆其起始地址在数据段的结尾处,而通过mmap分配的堆起始地址则在数据段后的随机偏移处。

      堆主要涉及到3种数据结构:

      (1):heap_info,即Heap Header。因为一个thread可以包含多个heap,在当前heap不够用时,系统就会通过mmap分配新的的heap添加到thread arena中,为了便于管理,每个heap都会包含一个heap_info.

      heap_info的数据结构:

    typedef struct _heap_info
    {
      mstate ar_ptr; /* Arena for this heap. */
      struct _heap_info *prev; /* Previous heap. */
      size_t size;   /* Current size in bytes. */
      size_t mprotect_size; /* Size in bytes that has been mprotected
                               PROT_READ|PROT_WRITE.  */
      /* Make sure the following data is properly aligned, particularly
         that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of
         MALLOC_ALIGNMENT. */
      char pad[-6 * SIZE_SZ & MALLOC_ALIGN_MASK];
    } heap_info;

      (2):malloc_state,即Arena Header,每个thread只有一个Arena Header,其包含bins,top chunk以及last remainder chunk等。

    struct malloc_state
    {
      /* Serialize access.  */
      mutex_t mutex;
      /* Flags (formerly in max_fast).  */
      int flags;
      /* 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;
      /* Linked list for free arenas.  */
      struct malloc_state *next_free;
      /* Memory allocated from the system in this arena.  */
      INTERNAL_SIZE_T system_mem;
      INTERNAL_SIZE_T max_system_mem;
    };

      (3):malloc_chunk,即Chunk Header,一个Heap被分为多个chunk,这个chunk的大小是由用户申请要分配的空间决定的(实际上chunk的可能大于用户申请分配的空间)

     1 struct malloc_chunk {
     2   /* #define INTERNAL_SIZE_T size_t */
     3   INTERNAL_SIZE_T      prev_size;  /* Size of previous chunk (if free).  */
     4   INTERNAL_SIZE_T      size;       /* Size in bytes, including overhead. */
     5   struct malloc_chunk* fd;         /* double links -- used only if free. 这两个指针只在free chunk中存在*/
     6   struct malloc_chunk* bk;
     7   /* Only used for large blocks: pointer to next larger size.  */
     8   struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
     9   struct malloc_chunk* bk_nextsize;
    10 };

     

      在glibc malloc中使用bin来管理空闲的chunk,其分为四类:fast bin,unsorted bin,small bin,large bin。

    (一):fast bin

    fast bin的个数只有10个,每一个fast bin都是由一个单链表构成。同一个链表中的所有chunk大小相同。默认情况下(以32位系统为例),每个bin之间按照步进8字节排列,即第一个bin的大小为8字节,第二个bin为16字节,以此类推。fast bin采用LIFO(后进先出)的原则,即最后进入链表的chunk会被最先分配。

    fast bin在malloc_state中的结构为:

    struct malloc_state
    {
      ……
      ……
      ……
      mfastbinptr fastbinsY[NFASTBINS]; //此为数组,用于存放10个fast bin
      ……
      ……
      ……
    };
  • 相关阅读:
    徒手画个disk不容易啊。。。
    fast powf
    SSE sqrt还是比C math库的sqrtf快了不少
    Mongoose也是个大坑
    A tiny program to benchmark image transpose algorithms
    On extracting ops from LLVM backend
    Into concurrent LRU caching once again
    性能大坑
    多项式在线拟合神器
    Spark 1.6.1源码编译
  • 原文地址:https://www.cnblogs.com/countfatcode/p/11490111.html
Copyright © 2020-2023  润新知