"Interpretación del código fuente de Malloc"

Después de leer parte del código fuente de malloc, el impacto es bastante profundo. También verifiqué algunas de mis propias ideas. Primero saque una parte del código fuente, esto es solo el comienzo.


/* V2.6.4-pt2 Sat Dec 14 1996

  This work is mainly derived from malloc-2.6.4 by Doug Lea
  <[email protected]>, which is available from:

                 ftp://g.oswego.edu/pub/misc/malloc.c

  Most of the original comments are reproduced in the code below.

* Why use this malloc?

  This is not the fastest, most space-conserving, most portable, or
  most tunable malloc ever written. However it is among the fastest
  while also being among the most space-conserving, portable and tunable.
  Consistent balance across these factors results in a good general-purpose
  allocator. For a high-level description, see
     http://g.oswego.edu/dl/html/malloc.html

  On many systems, the standard malloc implementation is by itself not
  thread-safe, and therefore wrapped with a single global lock around
  all malloc-related functions.  In some applications, especially with
  multiple available processors, this can lead to contention problems
  and bad performance.  This malloc version was designed with the goal
  to avoid waiting for locks as much as possible.  Statistics indicate
  that this goal is achieved in many cases.

* Synopsis of public routines

    SLE fieldE / * V2.6。4-pt2 1996年12月14日星期六这项工作主要来源于Doug Lea的malloc-2.6.4 <dl@cs。奥斯维戈。Edu >,
    可从:ftp://g.oswego。edu/pub/misc/malloc.c
    下面的代码复制了大部分原始注释。
    为什么使用这个malloc?

    这并不是最快、最节省空间、最可移植或最可调的malloc。
    然而,它是最快的,同时也是最节省空间,便携和可调的。
    这些因素之间的一致平衡产生了一个好的通用分配器。
    有关高级描述,请参见
            http://g.oswego。edu/dl/html/malloc.html

    在许多系统上,标准的malloc实现本身不是线程安全的,
    因此所有与malloc相关的函数都使用一个全局锁。在某些应用程序中,
    特别是使用多个可用处理器时,这可能导致争用问题和糟糕的性能。
    这个malloc版本的设计目标是尽可能避免等待锁。

    统计数据表明,这一目标在任何情况下都达到了。


  (Much fuller descriptions are contained in the program documentation below.)

  ptmalloc_init();
     Initialize global configuration.  When compiled for multiple threads,
     this function must be called once before any other function in the
     package.  It is not required otherwise.  It is called automatically
     in the Linux/GNU C libray or when compiling with MALLOC_HOOKS.
  malloc(size_t n);
     Return a pointer to a newly allocated chunk of at least n bytes, or null
     if no space is available.
  free(Void_t* p);
     Release the chunk of memory pointed to by p, or no effect if p is null.
  realloc(Void_t* p, size_t n);
     Return a pointer to a chunk of size n that contains the same data
     as does chunk p up to the minimum of (n, p's size) bytes, or null
     if no space is available. The returned pointer may or may not be
     the same as p. If p is null, equivalent to malloc.  Unless the
     #define REALLOC_ZERO_BYTES_FREES below is set, realloc with a
     size argument of zero (re)allocates a minimum-sized chunk.
  memalign(size_t alignment, size_t n);
     Return a pointer to a newly allocated chunk of n bytes, aligned
     in accord with the alignment argument, which must be a power of
     two.
  valloc(size_t n);
     Equivalent to memalign(pagesize, n), where pagesize is the page
     size of the system (or as near to this as can be figured out from
     all the includes/defines below.)
  pvalloc(size_t n);
     Equivalent to valloc(minimum-page-that-holds(n)), that is,
     round up n to nearest pagesize.
  calloc(size_t unit, size_t quantity);
     Returns a pointer to quantity * unit bytes, with all locations
     set to zero.
  cfree(Void_t* p);
     Equivalent to free(p).
  malloc_trim(size_t pad);
     Release all but pad bytes of freed top-most memory back
     to the system. Return 1 if successful, else 0.
  malloc_usable_size(Void_t* p);
     Report the number usable allocated bytes associated with allocated
     chunk p. This may or may not report more bytes than were requested,
     due to alignment and minimum size constraints.
  malloc_stats();
     Prints brief summary statistics on stderr.
  mallinfo()
     Returns (by copy) a struct containing various summary statistics.
  mallopt(int parameter_number, int parameter_value)
     Changes one of the tunable parameters described below. Returns
     1 if successful in changing the parameter, else 0.

     (更详细的描述包含在下面的程序文档中。)

ptmalloc_init ();
    初始化全局配置。当为多个线程编译时,
    类中的任何其他函数之前必须调用一次此函数
    包中。否则不需要。它是自动调用的
    在Linux/GNU C库或使用MALLOC_HOOKS编译时。
malloc (size_t n);
    返回一个指针,指向新分配的至少n个字节的块,或null
    如果没有可用空间。
 free(Void_t* p);
    释放p所指向的内存块,如果p为空则不释放。
realloc(Void_t* p, size_t n);
    返回一个指针,指向大小为n的包含相同数据的块
    同样,块p的最小值(n, p的大小)字节,或null
    如果没有可用空间。返回的指针可能是,也可能不是
    如果p为空,则等价于malloc。除非
    #定义realloc_zero_bytes_freees下面是设置,realloc与一个
    Size参数为0 (re)分配最小大小的块。
 memalign(size_t alignment, size_t n);
    返回一个指针,指向一个新分配的n字节的块,并对齐
    根据对齐论证,它必须是的幂两个。
valloc (size_t n);
    相当于memalign(pagesize, n),其中pagesize是页面
    系统的大小(或接近于此,可以从
    所有的包括/定义如下。)
pvalloc (size_t n);
    等价于valloc(minimum-page-that-hold (n)),即:
    四舍五入n到最接近的页面大小。
Calloc (size_t单位,size_t量);
    返回一个指向数量*单位字节的指针,其中包含所有位置
    设置为0。
cfree (Void_t * p);
    相当于free(p)。
malloc_trim (size_t垫);
    释放除了pad字节以外的所有已释放的最顶层内存
    对系统。如果成功返回1,否则返回0。
malloc_usable_size (Void_t * p);
    报告与已分配相关的可用已分配字节数
    这可能会报告比请求的字节多,也可能不会。
    由于对齐和最小尺寸限制。
malloc_stats ();
    打印stderr上的简要摘要统计信息。
mallinfo ()
    (通过复制)返回一个包含各种汇总统计信息的结构。
mallopt(int parameter_number, int parameter_value)
    更改下面描述的可调参数之一。返回
    如果成功更改参数,则为1,否则为0。

* Vital statistics:

  Alignment:                            8-byte
       8 byte alignment is currently hardwired into the design.  This
       seems to suffice for all current machines and C compilers.

  Assumed pointer representation:       4 or 8 bytes
       Code for 8-byte pointers is untested by me but has worked
       reliably by Wolfram Gloger, who contributed most of the
       changes supporting this.

  Assumed size_t  representation:       4 or 8 bytes
       Note that size_t is allowed to be 4 bytes even if pointers are 8.

  Minimum overhead per allocated chunk: 4 or 8 bytes
       Each malloced chunk has a hidden overhead of 4 bytes holding size
       and status information.

  Minimum allocated size: 4-byte ptrs:  16 bytes    (including 4 overhead)
                          8-byte ptrs:  24/32 bytes (including, 4/8 overhead)

       When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte
       ptrs but 4 byte size) or 24 (for 8/8) additional bytes are
       needed; 4 (8) for a trailing size field
       and 8 (16) bytes for free list pointers. Thus, the minimum
       allocatable size is 16/24/32 bytes.

       Even a request for zero bytes (i.e., malloc(0)) returns a
       pointer to something of the minimum allocatable size.

  Maximum allocated size: 4-byte size_t: 2^31 -  8 bytes
                          8-byte size_t: 2^63 - 16 bytes

       It is assumed that (possibly signed) size_t bit values suffice to
       represent chunk sizes. `Possibly signed' is due to the fact
       that `size_t' may be defined on a system as either a signed or
       an unsigned type. To be conservative, values that would appear
       as negative numbers are avoided.
       Requests for sizes with a negative sign bit will return a
       minimum-sized chunk.

  Maximum overhead wastage per allocated chunk: normally 15 bytes

       Alignment demands, plus the minimum allocatable size restriction
       make the normal worst-case wastage 15 bytes (i.e., up to 15
       more bytes will be allocated than were requested in malloc), with
       two exceptions:
         1. Because requests for zero bytes allocate non-zero space,
            the worst case wastage for a request of zero bytes is 24 bytes.
         2. For requests >= mmap_threshold that are serviced via
            mmap(), the worst case wastage is 8 bytes plus the remainder
            from a system page (the minimal mmap unit); typically 4096 bytes.

*重要统计数字:

  对齐 :                            8字节
    8字节对齐目前是硬连接到设计中。这
    似乎对当前所有的机器和C编译器都足够了。

  假设指针表示:4或8字节
    8字节指针的代码没有经过我的测试,但已经工作
    由Wolfram Gloger,谁贡献了大部分
    支持此功能的更改。

  假设size_t表示:4或8字节
    注意,即使指针为8,size_t也允许为4字节。

    每个已分配块的最小开销:4或8字节
    每个错误锁定的块都有4个字节的隐藏开销
    以及状态信息。

 最小分配大小:4字节ptrs: 16字节(包括4个开销)
    8字节ptrs: 24/32字节(包括4/8开销)

 当一个块被释放时,12(对于4字节的ptrs)或20(对于8字节的ptrs)
    PTRS但4字节大小)或24(8/8)额外的字节
    需要;4(8)用于尾随大小字段
    8(16)字节的空闲列表指针。因此,最小值
    可分配大小为16/24/32字节。

    即使是零字节的请求(即malloc(0))也会返回一个
    指向最小可分配大小的指针。

 最大分配大小:4字节size_t: 2^31 - 8字节            //这里解释一下,内存分配最大是size_t 
    size_t:2^63 - 16字节                          //众所周知的size_t是一个无符号int。
    假设大小为t的位值(可能带符号)就足够了            //因为足够了。解释的很清楚!
    表示块大小。               //为什么不用有负号? 引入负数又可能会带来哲学上的问题。                                                                      
    可能有符号'是因为大小t'在系统中可以定义为有符号类型或无符号类型。 //你会申请负内存吗?
    为了保守起见,将避免显示为负数的值。    //不会,因为根本没有负内存系统,计算机也没负数,                                
    请求带有负号位的大小将返回最小大小的块。 //如果你能了解计算机负数怎么存的,应该很快就能明白。
                                          //所以这里的说明对size_t 进行了充分的解释。           
 每个已分配块的最大开销浪费:通常为15字节

    对齐要求,加上最小可分配的大小限制
    使正常的最坏情况的浪费15字节(即,高达15
    分配的字节将比malloc中请求的字节多
    两个例外:
        1. 因为零字节的请求分配的是非零空间,
    对于零字节的请求,最坏情况下的浪费是24字节。
        2. 对于通过&gt;= mmap_threshold服务的请求
    Mmap(),最坏情况下的浪费是8字节加上余数
    从一个系统页面(最小的mmap单元);通常是4096字节。


* Limitations

    Here are some features that are NOT currently supported

    * No automated mechanism for fully checking that all accesses
      to malloced memory stay within their bounds.
    * No support for compaction.

* Synopsis of compile-time options:

    People have reported using previous versions of this malloc on all
    versions of Unix, sometimes by tweaking some of the defines
    below. It has been tested most extensively on Solaris and
    Linux. People have also reported adapting this malloc for use in
    stand-alone embedded systems.

    The implementation is in straight, hand-tuned ANSI C.  Among other
    consequences, it uses a lot of macros.  Because of this, to be at
    all usable, this code should be compiled using an optimizing compiler
    (for example gcc -O2) that can simplify expressions and control
    paths.

  __STD_C                  (default: derived from C compiler defines)
     Nonzero if using ANSI-standard C compiler, a C++ compiler, or
     a C compiler sufficiently close to ANSI to get away with it.
  MALLOC_DEBUG             (default: NOT defined)
     Define to enable debugging. Adds fairly extensive assertion-based
     checking to help track down memory errors, but noticeably slows down
     execution.
  MALLOC_HOOKS             (default: NOT defined)
     Define to enable support run-time replacement of the allocation
     functions through user-defined `hooks'.
  REALLOC_ZERO_BYTES_FREES (default: NOT defined)
     Define this if you think that realloc(p, 0) should be equivalent
     to free(p). Otherwise, since malloc returns a unique pointer for
     malloc(0), so does realloc(p, 0).
  HAVE_MEMCPY               (default: defined)
     Define if you are not otherwise using ANSI STD C, but still
     have memcpy and memset in your C library and want to use them.
     Otherwise, simple internal versions are supplied.
  USE_MEMCPY               (default: 1 if HAVE_MEMCPY is defined, 0 otherwise)
     Define as 1 if you want the C library versions of memset and
     memcpy called in realloc and calloc (otherwise macro versions are used).
     At least on some platforms, the simple macro versions usually
     outperform libc versions.
  HAVE_MMAP                 (default: defined as 1)
     Define to non-zero to optionally make malloc() use mmap() to
     allocate very large blocks.
  HAVE_MREMAP                 (default: defined as 0 unless Linux libc set)
     Define to non-zero to optionally make realloc() use mremap() to
     reallocate very large blocks.
  malloc_getpagesize        (default: derived from system #includes)
     Either a constant or routine call returning the system page size.
  HAVE_USR_INCLUDE_MALLOC_H (default: NOT defined)
     Optionally define if you are on a system with a /usr/include/malloc.h
     that declares struct mallinfo. It is not at all necessary to
     define this even if you do, but will ensure consistency.
  INTERNAL_SIZE_T           (default: size_t)
     Define to a 32-bit type (probably `unsigned int') if you are on a
     64-bit machine, yet do not want or need to allow malloc requests of
     greater than 2^31 to be handled. This saves space, especially for
     very small chunks.
  _LIBC                     (default: NOT defined)
     Defined only when compiled as part of the Linux libc/glibc.
     Also note that there is some odd internal name-mangling via defines
     (for example, internally, `malloc' is named `mALLOc') needed
     when compiling in this case. These look funny but don't otherwise
     affect anything.
  LACKS_UNISTD_H            (default: undefined)
     Define this if your system does not have a <unistd.h>.
  MORECORE                  (default: sbrk)
     The name of the routine to call to obtain more memory from the system.
  MORECORE_FAILURE          (default: -1)
     The value returned upon failure of MORECORE.
  MORECORE_CLEARS           (default 1)
     True (1) if the routine mapped to MORECORE zeroes out memory (which
     holds for sbrk).
  DEFAULT_TRIM_THRESHOLD
  DEFAULT_TOP_PAD
  DEFAULT_MMAP_THRESHOLD
  DEFAULT_MMAP_MAX
     Default values of tunable parameters (described in detail below)
     controlling interaction with host system routines (sbrk, mmap, etc).
     These values may also be changed dynamically via mallopt(). The
     preset defaults are those that give best performance for typical
     programs/systems.
  DEFAULT_CHECK_ACTION
     When the standard debugging hooks are in place, and a pointer is
     detected as corrupt, do nothing (0), print an error message (1),
     or call abort() (2).



*限制

以下是目前不支持的一些功能

    *没有完全检查所有访问的自动化机制
    对错误的内存保持在他们的范围内。
    *不支持压缩。

编译时选项简介:

    人们已经报告在所有应用程序上使用此malloc的先前版本
    Unix版本,有时通过调整一些定义
    在下面。它在Solaris上进行了最广泛的测试
    Linux。人们也报道了将这种malloc用于
    独立嵌入式系统。

    实现是直接的、手动调优的ANSI c
    它使用了很多宏。正因为如此,才会在
    所有可用的代码都应该使用优化编译器编译
    (例如gcc -O2),可以简化表达式和控制
    路径。

    __STD_C(默认值:从C编译器定义派生)
    如果使用ansi标准C编译器、c++编译器或
    一个足够接近ANSI的C编译器。
MALLOC_DEBUG(默认值:未定义)
    定义以启用调试。添加相当广泛的基于断言的功能
    检查有助于跟踪内存错误,但速度明显变慢
    执行。
MALLOC_HOOKS(默认值:未定义)
    定义以启用支持分配的运行时替换
    通过用户定义的“钩子”函数。
REALLOC_ZERO_BYTES_FREES(默认值:未定义)
    如果您认为realloc(p, 0)应该是等价的,那么就定义它
    免费(p)。否则,由于malloc返回一个唯一的指针
    Malloc (0) realloc(p, 0)也是。
HAVE_MEMCPY(默认值:已定义)
    定义如果你不是使用ANSI STD C,但仍然
    在你的C库中有memcpy和memset,并且想要使用它们。
    否则,将提供简单的内部版本。
USE_MEMCPY(默认值:1,如果定义了HAVE_MEMCPY,否则为0)
    如果需要memset的C库版本,则定义为1
    在realloc和calloc中调用Memcpy(否则使用宏版本)。
    至少在某些平台上,通常是简单的宏版本
    优于libc版本。
HAVE_MMAP(默认:定义为1)
    定义为非零可选择性地使malloc()使用mmap() to
    分配非常大的块。
HAVE_MREMAP(默认:定义为0,除非Linux libc设置)
    定义为非零可选择性地使realloc()使用mremap() to
    重新分配非常大的块。
Malloc_getpagesize(默认值:从system# includes派生)
    返回系统页大小的常量或例程调用。
    HAVE_USR_INCLUDE_MALLOC_H(默认:未定义)
    如果系统中有/usr/include/malloc.h,则可选定义
    它声明了struct mallinfo。完全没有必要
    即使你这样做了,也要定义它,但要确保一致性。
    INTERNAL_SIZE_T(默认值:size_t)
    定义为32位类型(可能是' unsigned int')
    64位机器,但不希望或需要允许的malloc请求
    大于2^31要处理。这样可以节省空间,特别是对于
    非常小的块。
_LIBC(默认值:未定义)
    仅在编译为Linux libc/glibc的一部分时定义。
    还要注意,通过定义有一些奇怪的内部名称混乱
    (例如,在内部,' malloc'被命名为' malloc')
    在这种情况下编译时。这些看起来很有趣,但其实不然
    影响任何东西。
LACKS_UNISTD_H(默认:undefined)
    如果您的系统没有&lt;unist .h&gt;
MORECORE(默认:sbrk)
    要从系统中获取更多内存而调用的例程的名称。
MORECORE_FAILURE(默认值:-1)
    MORECORE失败时返回的值。

MORECORE_CLEARS           (default 1)
    如果映射到MORECORE的例程清空内存,则为True (1)
    坚持sbrk)。
DEFAULT_TRIM_THRESHOLD
DEFAULT_TOP_PAD
DEFAULT_MMAP_THRESHOLD
DEFAULT_MMAP_MAX
    可调参数的默认值(下面将详细描述)
    控制与主机系统例程(sbrk, mmap等)的交互。
    这些值也可以通过mallopt()动态更改。的
    预设默认值是那些为典型提供最佳性能的默认值
    程序/系统。
DEFAULT_CHECK_ACTION
    当标准调试钩子就位时,指针是
    检测到已损坏,什么都不做(0),打印错误消息(1),
    或者调用abort()(2)。
*/

/*

* Compile-time options for multiple threads:

  USE_PTHREADS, USE_THR, USE_SPROC
     Define one of these as 1 to select the thread interface:
     POSIX threads, Solaris threads or SGI sproc's, respectively.
     If none of these is defined as non-zero, you get a `normal'
     malloc implementation which is not thread-safe.  Support for
     multiple threads requires HAVE_MMAP=1.  As an exception, when
     compiling for GNU libc, i.e. when _LIBC is defined, then none of
     the USE_... symbols have to be defined.

  HEAP_MIN_SIZE
  HEAP_MAX_SIZE
     When thread support is enabled, additional `heap's are created
     with mmap calls.  These are limited in size; HEAP_MIN_SIZE should
     be a multiple of the page size, while HEAP_MAX_SIZE must be a power
     of two for alignment reasons.  HEAP_MAX_SIZE should be at least
     twice as large as the mmap threshold.
  THREAD_STATS
     When this is defined as non-zero, some statistics on mutex locking
     are computed.


*多线程的编译时选项:

Use_pthreads, use_thr, use_sproc
    将其中一个定义为1以选择线程接口:
    POSIX线程、Solaris线程或SGI sproc线程。
    如果这些都不被定义为非零,你就会得到一个"正态"
    不是线程安全的Malloc实现。支持
    多线程要求HAVE_MMAP=1。作为例外,当
    编译GNU libc,即当_LIBC被定义时,则没有
    USE_……符号必须被定义。

HEAP_MIN_SIZE
HEAP_MAX_SIZE
    当线程支持被启用时,额外的堆将被创建
    使用mmap调用。它们的规模有限;HEAP_MIN_SIZE应该
    是页面大小的倍数,而HEAP_MAX_SIZE必须是幂
    因为对齐的原因。HEAP_MAX_SIZE应该至少是
    是mmap阈值的两倍。
THREAD_STATS
    当此值被定义为非零时,互斥锁的一些统计信息
    计算。

* /
*/

Continuará~

Supongo que te gusta

Origin blog.csdn.net/qq_36912885/article/details/129368673
Recomendado
Clasificación