我是UNIX新手,我正在研究一些UNIX系统调用,例如brk()
,sbrk()
等等。
最后一天我读到了malloc()
函数,我感到很困惑!
任何人都可以告诉我为什么malloc减少了程序必须执行的sbrk()
系统调用的数量?
另一个问题是,brk(0)
,sbrk(0)
和malloc(0)
会返回相同的值吗?
答案 0 :(得分:32)
由于系统调用所带来的额外开销,Syscalls的处理成本很高:您必须切换到内核模式。系统调用通过发出“陷阱”或中断进入内核。它是对内核的一个服务调用,因为它在内核地址空间中执行,所以它有一个很高的开销到内核(然后切换回来)。
这就是为什么malloc
会减少对sbrk()
和brk()
的通话次数的原因。它通过请求比你要求更多的内存来实现这一点,因此每次需要更多内存时都不必发出系统调用。
brk()
和sbrk()
不同。
brk
用于将数据段的结尾设置为您指定的值。它说“将我的数据段的末尾设置为此地址”。当然,您指定的地址必须合理,操作系统必须有足够的内存,并且您不能指向某个超出进程最大数据大小的地方。因此,brk(0)
无效,因为您尝试将数据段的结尾设置为地址0
,这是无意义的。
另一方面,sbrk
将数据段大小增加您指定的数量,并返回指向上一个中断值的指针。使用0调用sbrk
是有效的;它是一种获取指向当前数据段中断地址的指针的方法。
malloc
不是系统调用,它是使用sbrk
管理内存的C库函数。根据联机帮助页,malloc(0)
是有效的,但没有多大用处:
如果size为0,则malloc()返回NULL或唯一指针 以后可以成功传递给free()的值。
所以,不,brk(0)
,sbrk(0)
和malloc(0)
不等价:第一个是无效的,第二个用于获取程序中断的地址,以及后者没用。
请注意,您不应在整个计划中同时使用malloc
和brk
或sbrk
。 malloc
假设它完全控制brk
和sbrk
,如果您与malloc
和brk
互换,可能会发生非常奇怪的事情。
答案 1 :(得分:5)
为什么malloc减少了程序的sbrk()系统调用次数 必须执行?
比如说,如果你调用malloc()来请求10字节内存,实现可能会使用sbrk(或其他系统调用,如mmap)从OS请求4K字节。然后当你下次再调用malloc()请求另外10个字节时,它不必发出系统调用;它可能只返回上一次4K系统调用分配的内存。
答案 2 :(得分:1)
malloc()函数用于调用sbrk系统调用以在进程中动态创建内存。
malloc()函数已在stdlib.h头文件中分配,因此使用库函数通过malloc函数递归调用所需函数。
在sbrk的帮助下,我们需要明确声明一些事情来调用系统调用。
根据函数或系统调用中给出的大小,它返回变量并存储。
答案 3 :(得分:0)
sbrk()
函数按指定的字节增加程序数据段分配。
malloc(4096); // sbrk += 4096 Bytes
free(); // freeing memory will not bring down the sbrk by 4096 Bytes
malloc(4096); // malloc'ing again will not increase the sbrk and it will use
the existing space which not result in sbrk() call.