通常如何实现堆?
可能重复:
如何管理,实施和分配堆和堆栈内存?
嗨,我的问题是关于堆,而不是数据结构,但用于动态内存分配的内存区域。
假设我们用C语言(或者C ++)编写程序,并且在其代码的深处某处调用malloc()(或者在C ++的情况下调用operator new)。 现在分配的内存的位置是什么? 编译器(链接器?)是否添加用作堆的数据段? 该细分受众群的规模如何确定? 如果我们尝试分配比整个“堆段”更大的内存块,会发生什么? 堆会扩大吗? 如果是,如何?
操作系统分配页面,将其返回到malloc / free,然后将这些页面从内存中分解成请求大小的块。 操作系统可以分配用户地址空间中尚未请求的任何页面。 没有堆段。 分配的内存位于OS确定的任何位置。
这里描述了dlmalloc(在glibc,uClibc和其他许多地方使用的malloc()实现)的内部工作原理。
类Unix操作系统有两个用于请求/释放内存的主要接口:
Windows API实际上就像malloc()/ free()一样,具有像HeapAlloc()/ HeapFree()这样的函数。
旧的unix实现使用机制sbrk()
请求移动最后的数据部分边界。 内存分配时,通用时间库调用系统将数据边界向上移动,并使用新来的内存。
新的操作系统使用虚拟内存,所以malloc在必要时向系统请求新的免费虚拟机页面。
独立应用程序(在裸机,微控制器等上运行)都分配了内存。 库知道所有内存,因为链接器脚本定义了动态区域的符号。 例如, 像freemembot
和freememtop
,可用于最低和最高空闲内存区域位置。