并非所有 malloc 的内存都是 "heap" 并且每个块在虚拟内存中都不连续?
not all malloc'ed memory is "heap" and each block is not contiguous in virtual memory?
似乎 malloc
在内部调用 mmap
为 :
//not 100% correct onlyfor demo purpose
// void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
void *malloc(size_t size){
...
mmap(NULL, size,...);
...
}
所以malloc
传递NULL
作为mmap
的第一个参数作为起始地址,所以内核会选择一个合适的虚拟地址进行映射,这意味着malloc
不一定会在堆区(由brk
指针指示)创建映射。
如果这是真的,那意味着在多次 malloc
调用之后,虚拟内存中的每个块之间会有很多间隙,因为每个 malloc
return 一个新的虚拟地址与前一个不连续,那些虚拟地址与 brk
无关,所以一旦我们释放了一个特定的块,那么我们就不能将相邻的空闲块与我们释放的块合并,因为每个块在虚拟中都不连续内存,那这样动态分配内存是不是很低效?
在 malloc
中使用 mmap
用于 大块 的原因正是当块被释放时,它可以被 OS 当它被 munmap
ped.
这与标准 brk/sbrk“堆”不同,在标准“堆”中几乎不可能移动程序崩溃,只是因为使用堆正是为了 allocations/deallocations 需要没有按照精确的 LIFO 顺序发生 - 那么你唯一的希望就是尝试合并相邻的空闲内存块......
似乎 malloc
在内部调用 mmap
为 :
//not 100% correct onlyfor demo purpose
// void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
void *malloc(size_t size){
...
mmap(NULL, size,...);
...
}
所以malloc
传递NULL
作为mmap
的第一个参数作为起始地址,所以内核会选择一个合适的虚拟地址进行映射,这意味着malloc
不一定会在堆区(由brk
指针指示)创建映射。
如果这是真的,那意味着在多次 malloc
调用之后,虚拟内存中的每个块之间会有很多间隙,因为每个 malloc
return 一个新的虚拟地址与前一个不连续,那些虚拟地址与 brk
无关,所以一旦我们释放了一个特定的块,那么我们就不能将相邻的空闲块与我们释放的块合并,因为每个块在虚拟中都不连续内存,那这样动态分配内存是不是很低效?
在 malloc
中使用 mmap
用于 大块 的原因正是当块被释放时,它可以被 OS 当它被 munmap
ped.
这与标准 brk/sbrk“堆”不同,在标准“堆”中几乎不可能移动程序崩溃,只是因为使用堆正是为了 allocations/deallocations 需要没有按照精确的 LIFO 顺序发生 - 那么你唯一的希望就是尝试合并相邻的空闲内存块......