1. 堆(heap)
关于操作系统的内存管理的具体内容可以看《深入了解计算机系统》第九章——虚拟存储器。
进程内存分布图如下:
动态内存分布主要发生在heap上,对于每个进程,内核维护一个变量brk,指向heap的顶部。访问超过brk的地址,将会发生错误。
那么heap是什么呢?
heap是一组不同大小的块(block)的集合。每个块就是一个连续的虚拟存储器片(chuank),要么是已分配的,要么是空闲的。
以隐式空闲链表来实现堆为例:
每个块的结构如上图所示,头部、有效荷载和填充。头部说明了块的大小以及是已分配还是空闲。头部以后是malloc请求的有效荷载。那么这样的话,可以讲堆视为一个连续的已分配块和空闲块的序列:
那么,当malloc申请动态内存时,分配器会寻找一个合适的块来分配出去——这里可能涉及到分割空闲块。如果没有合适的块,那么分配器会调用sbrk函数,向内核请求额外的堆存储器。同时,分配器可能会合并空闲块。具体实现在这个问题里不需要关注,总之所有的方法都是为了处理以下四个问题: