如果malloc / free在libc中作为库例程实现,那么它是在sbrk系统调用还是mmap系统调用之上实现的,还是其他的?
而一般来说,在sys / syscall.h中声明的函数是否包含目标机器中的所有系统调用?
malloc
和free
是标准C库函数,这些函数将由每个C实现来实现。
C标准只定义了这些函数的行为方式和行为。 它们如何在每个实现的左侧实现。
简而言之,它们是您使用的实现的实现细节。
(一个“实现”由编译器,链接器,运行时库以及其他一些东西组成。)
很多时候, malloc
和free
都使用较低级别的虚拟内存分配服务,并使用像mmap和munmap (也许是sbrk )这样的系统调用一次分配几个页面(甚至是兆字节)。 通常, malloc
更喜欢在相关时重用先前的 free
内存空间。 大多数malloc
实现为“大”和“小”分配等使用各种不同的策略。
注意, 虚拟地址空间可以是有限的,例如setrlimit(2) 。 在Linux pmap(1)和proc(5)上使用,以了解更多关于某个进程的虚拟地址空间的信息(例如/proc/self/maps
for your own or /proc/1234/maps
– 也可以是pmap 1234
命令pid 1234的过程)。
您可以查看您的GNU libc源代码,查看其他C标准库(如musl-libc )的源代码,阅读有关malloc
实现 ,选择其他一些或实现自己的代码,或者使用strace来实验性地查找。
请阅读系统调用手册页 (即syscalls(2) )和文件<asm/unistd.h>
以获取系统调用列表。
malloc
(我相信这可能是malloc
的最快实现;但是它不是很有用,它符合标准)
我坚信C标准对malloc
和free
很模糊。 我很确定下面的功能是尊重标准的字母(但不是精神):
/* politically incorrect, but very probably standard conforming */ void *malloc (size_t sz) { errno = ENOMEM; return NULL; } void free(void*ptr) { }
(顺便说一句,每个使用malloc
代码都应该对其失败进行测试,但是一些-incorrectly-不; malloc
可以在失败时返回NULL
,并且人们应该针对这种情况进行测试)
GNU libc为您提供了自己的malloc
函数的钩子 (甚至可能透过它们使用Boehm的垃圾收集器 )。 这些挂钩可能会被弃用,而且不是标准的。
如果使用GNU libc,请参阅mallinfo(3)和malloc_stat(3)及相关函数。
如果你使用不同的内存分配器,你也可以使用malloc
替代实现。 例如, 囤积内存分配器有时用于提高多线程应用程序的性能。