如何在没有系统调用的情况下在堆上分配内存?

时间:2021-09-27 04:01:06

I was wondering that if the space required on heap is not large enough such that there is no need for a brk/sbrk system all (to shift the break pointer (brk) of data segment), how does a library function (such as malloc) allocates space on heap. I am not asking about the data-structures and algorithms for heap management. I am just asking how does malloc get the address of the first location of the heap if it doesn't invoke a system call. I am asking this because I have heard that it is not always necessary to invoke a system call (brk/sbrk) as these are only required to expand the space.Please correct me if I am wrong.

我想知道如果堆上所需的空间不够大,以至于不需要所有的brk / sbrk系统(移动数据段的中断指针(brk)),库函数如何(例如malloc) )在堆上分配空间。我不是在询问堆管理的数据结构和算法。我只是问如果malloc没有调用系统调用,它如何获取堆的第一个位置的地址。我问这个是因为我听说并不总是需要调用系统调用(brk / sbrk),因为这些只需要扩展空间。如果我错了,请纠正我。

3 个解决方案

#1


3  

The basic idea is that when your program starts, the heap is very small, but not necessarily zero. If you only allocate (malloc) a small amount of memory, the library is able to handle it within the small amount of space it has when it is loaded. However, when malloc runs out of that space, it needs to make a system call to get more memory.

基本思想是,当程序启动时,堆非常小,但不一定是零。如果只分配(malloc)少量内存,则库可以在加载时占用少量空间。但是,当malloc用完该空间时,需要进行系统调用以获得更多内存。

That system call is often sbrk(), which moves the top of the heap's memory region up by a certain amount. Usually, the malloc library routine increases the heap by larger than what is needed for the current allocation, with the hope that future allocations can be performed w/o making a system call.

该系统调用通常是sbrk(),它将堆的内存区域的顶部向上移动一定量。通常,malloc库例程将堆大于当前分配所需的堆,希望未来的分配可以在不进行系统调用的情况下执行。

Other implementations of malloc use mmap() instead -- this allows the program to create a sparse virtual memory mapping. However, mmap() based malloc implementations do the same thing as the sbrk()-based ones: each system call reserves more memory than what is necessarily needed for the current call.

malloc的其他实现使用mmap()代替 - 这允许程序创建稀疏虚拟内存映射。但是,基于mmap()的malloc实现与基于sbrk()的实现相同:每个系统调用保留的内存多于当前调用所需的内存。

One way to look at this is to trace a program that uses malloc: you'll see that for N calls to malloc, you will see M system calls (where M is much smaller than N).

查看此问题的一种方法是跟踪使用malloc的程序:您将看到对于对malloc的N次调用,您将看到M系统调用(其中M远小于N)。

#2


2  

The short answer is that it uses sbrk() to allocate a big hunk, which at that point belongs to your app process. It can then further parcel out subsections of that as individual malloc calls without needing to ask the system for anything, until it exhausts that space and needs to resort sbrk() again.

简短的回答是它使用sbrk()来分配一个大块,在那时它属于你的app进程。然后,它可以进一步分割出单个malloc调用的子部分,而无需向系统询问任何内容,直到它耗尽该空间并需要再次使用sbrk()。

You said you didn't want the details on the data structures, but suffice it to say that the implementation of malloc (i.e. your own process, not the OS kernel) is keeping track of which space in the region it got from the system is spoken for and which is still available to dole out as individual mallocs. It's like buying a big tract of land, then subdividing it into lots for individual houses.

你说你不想要数据结构的细节,但是足以说malloc的实现(即你自己的进程,而不是OS内核)跟踪它从系统获得的区域中的哪个空间是所说的,仍然可以作为单独的mallocs发布。这就像购买大片土地,然后将其细分为个别房屋。

#3


-1  

Use sbrk() or mmap() — http://linux.die.net/man/2/sbrk, http://linux.die.net/man/2/mmap

使用sbrk()或mmap() - http://linux.die.net/man/2/sbrk,http://linux.die.net/man/2/mmap

#1


3  

The basic idea is that when your program starts, the heap is very small, but not necessarily zero. If you only allocate (malloc) a small amount of memory, the library is able to handle it within the small amount of space it has when it is loaded. However, when malloc runs out of that space, it needs to make a system call to get more memory.

基本思想是,当程序启动时,堆非常小,但不一定是零。如果只分配(malloc)少量内存,则库可以在加载时占用少量空间。但是,当malloc用完该空间时,需要进行系统调用以获得更多内存。

That system call is often sbrk(), which moves the top of the heap's memory region up by a certain amount. Usually, the malloc library routine increases the heap by larger than what is needed for the current allocation, with the hope that future allocations can be performed w/o making a system call.

该系统调用通常是sbrk(),它将堆的内存区域的顶部向上移动一定量。通常,malloc库例程将堆大于当前分配所需的堆,希望未来的分配可以在不进行系统调用的情况下执行。

Other implementations of malloc use mmap() instead -- this allows the program to create a sparse virtual memory mapping. However, mmap() based malloc implementations do the same thing as the sbrk()-based ones: each system call reserves more memory than what is necessarily needed for the current call.

malloc的其他实现使用mmap()代替 - 这允许程序创建稀疏虚拟内存映射。但是,基于mmap()的malloc实现与基于sbrk()的实现相同:每个系统调用保留的内存多于当前调用所需的内存。

One way to look at this is to trace a program that uses malloc: you'll see that for N calls to malloc, you will see M system calls (where M is much smaller than N).

查看此问题的一种方法是跟踪使用malloc的程序:您将看到对于对malloc的N次调用,您将看到M系统调用(其中M远小于N)。

#2


2  

The short answer is that it uses sbrk() to allocate a big hunk, which at that point belongs to your app process. It can then further parcel out subsections of that as individual malloc calls without needing to ask the system for anything, until it exhausts that space and needs to resort sbrk() again.

简短的回答是它使用sbrk()来分配一个大块,在那时它属于你的app进程。然后,它可以进一步分割出单个malloc调用的子部分,而无需向系统询问任何内容,直到它耗尽该空间并需要再次使用sbrk()。

You said you didn't want the details on the data structures, but suffice it to say that the implementation of malloc (i.e. your own process, not the OS kernel) is keeping track of which space in the region it got from the system is spoken for and which is still available to dole out as individual mallocs. It's like buying a big tract of land, then subdividing it into lots for individual houses.

你说你不想要数据结构的细节,但是足以说malloc的实现(即你自己的进程,而不是OS内核)跟踪它从系统获得的区域中的哪个空间是所说的,仍然可以作为单独的mallocs发布。这就像购买大片土地,然后将其细分为个别房屋。

#3


-1  

Use sbrk() or mmap() — http://linux.die.net/man/2/sbrk, http://linux.die.net/man/2/mmap

使用sbrk()或mmap() - http://linux.die.net/man/2/sbrk,http://linux.die.net/man/2/mmap