我是UNIX的新手,我正在研究一些UNIX系统调用,如brk()
,sbrk()
等。
昨天我读了malloc()
函数,我有点困惑!谁能告诉我为什么 malloc 减少了程序必须执行的sbrk()
系统调用的数量?
还有一个问题,brk(0)
、sbrk(0)
和 malloc(0)
返回相同的值吗?
系统调用的处理成本很高,因为系统调用会产生额外的开销:您必须切换到内核模式。系统调用通过发出"陷阱"或中断进入内核。它是对服务的内核的调用,并且由于它在内核地址空间中执行,因此它有一个高开销切换到内核(然后切换回来)。
这就是为什么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
,就会发生非常奇怪的事情。
为什么 malloc 减少了程序对 sbrk() 系统调用的数量 必须执行?
比如说,如果你调用 malloc() 来请求 10 字节的内存,实现可能会使用 sbrk(或其他系统调用,如 mmap)从操作系统请求 4K 字节。然后,当您下次调用 malloc() 请求另外 10 个字节时,它不必发出系统调用;它可能只是返回上次 4K 的系统调用分配的一些内存。
>malloc() 函数用于调用 sbrk 系统调用以在此过程中动态创建内存。
malloc() 函数已经在 stdlib.h 头文件中分配,因此 AS 根据所需的函数由 malloc 函数使用库函数递归调用。
在 sbrk 的帮助下,我们需要显式声明一些东西来调用系统调用。
根据函数中给出的大小或通过系统调用它返回到变量并存储。
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.