small object 和 large object 的分配流程为:1)先从 tcache 分配;2)tcache 分配不成功,从 arena 分配;3) arena 不成功,从 system memory 分配。
small object 和 large object 的一个区别在于:分配 small object 的时候,如果是从arena 或 memory system 进行分配的话,会分配多一些内存,多余的内存由 tcache 进行缓存,下一次请求可以使用;分配 large object 的时候,只会分配申请的内存。
分配 huge object 的时候,直接采用 mmap 从 system memory 中申请,并独立维护。
jemalloc 的层级结构
回收内存
内存回收的逻辑和内存分配的逻辑刚好相反。
small object 和 large object 回收的时候,先放回 tcache。
huge object 回收的时候,直接调用 munmap 将内存释放给内核就行。
tcahe 缓存的内存满时会触发释放到 arena;arena 缓存的内存满时会触发释放到 system memory。
上图是一个 Linux 64位进程的地址空间布局的简图,jemalloc 能管理的就是 Heap 和 Memory map 两块的内存。
Text,存储程序的二进制代码。
Data,存储已初始化的全局数据。
BSS,存储未初始化的全局数据。
几个随机起始地址主要用于防止溢出攻击。
brk/sbrk
代码语言:javascript
复制
#include <unistd.h>
int brk(void *addr);
void *sbrk(intptr_t increment);
brk() and sbrk() change the location of the program break, which defines the end of the process's data segment (i.e., the program break is the first location after the end of the uninitialized data segment). Increasing the program break has the effect of allocating memory to the process; decreasing the break deallocates memory.