Glibc内存管理--ptmalloc2源代码分析(六)

3.2.3.4 sbrkmmap 

从进程的内存布局可知,.bss 段之上的这块分配给用户程序的空间被称为heap (堆)。start_brk指向heap的开始,而brk指向heap的顶部。可以使用系统调用brk()sbrk()来增加标识heap顶部的brk值,从而线性的增加分配给用户的heap空间。在使malloc之前,brk的值等于start_brk,也就是说heap大小为0ptmalloc在开始时,若请求的空间小于 mmap分配阈值(mmap threshold,默认值为128KB)时,主分配区会调用sbrk()增加一块大小为 (128 KB + chunk_size) align 4KB的空间作为heap。非主分配区会调用mmap映射一块大小为HEAP_MAX_SIZE32位系统上默认为1MB64位系统上默认为64MB的空间作为sub-heap这就是前面所说的ptmalloc 所维护的分配空间,当用户请求内存分配时,首先会在这个区域内找一块合适的chunk给用户。当用户释放了heap 中的chunk时,ptmalloc又会使用fast binsbins来组织空闲chunk。以备用户的下一次分配。若需要分配的chunk大小小于mmap分配阈值,而heap空间又不够,则此时主分配区会通过sbrk()调用来增加heap大小,非主分配区会调用mmap映射一块新的sub-heap,也就是增加top chunk的大小,每次heap增加的值都会对齐到4KB

当用户的请求超过mmap分配阈值,并且主分配区使用sbrk()分配失败的时候,或是非主分配区top chunk中不能分配到需要的内存时,ptmalloc会尝试使用mmap()直接映射一块内存到进程内存空间。使用mmap()直接映射的chunk在释放时直接解除映射,而不再属于进程的内存空间。任何对该内存的访问都会产生段错误。而在heap中或是sub-heap中分配的空间则可能会留在进程内存空间内,还可以再次引用(当然是很危险的)。

ptmalloc munmap chunk时,如果回收的chunk空间大小大于mmap分配阈值的当前值,并且小于DEFAULT_MMAP_THRESHOLD_MAX32位系统默认为512KB64位系统默认为32MB),ptmalloc会把mmap分配阈值调整为当前回收的chunk的大小,并将mmap收缩阈值(mmap trim threshold)设置为mmap分配阈值的2倍。这就是ptmalloc的对mmap分配阈值的动态调整机制,该机制是默认开启的,当然也可以用mallopt()关闭该机制(将在3.2.6节介绍如何关闭该机制)。

你可能感兴趣的:(malloc)