当我们使用new来分配内存时,操作系统会做什么样的簿记?

时间:2011-04-22 04:17:31

标签: c++ memory-management new-operator

除了记住对象指针的地址外,我认为操作系统还需要记录内存大小的大小。因此,当我们使用delete时,操作系统将知道要释放多少内存。

有人可以告诉我更多关于此的细节吗?还记录了哪些其他信息?那些信息存储在哪里?删除内存后操作系统会做什么?

2 个答案:

答案 0 :(得分:3)

如前所述,new是一个库函数,而不是一个OS功能。

一般情况大致如下:

  • C ++编译器将new关键字转换为malloc()(或等效的)函数调用

  • 分配器保留一个空闲的内存块列表,在那里搜索最佳匹配。

  • 通常情况下,“最佳”匹配值大于您的计划要求的金额。如果是这样,分配器将分割块,标记一个大小(可能还有一些其他元数据),将其余的放回到空闲列表中,并将分配的块返回给您的程序。

  • 如果找不到合适的空闲块,分配器会从操作系统请求一些内存块。有几种方法可以做到这一点,但它通常被认为是一个缓慢的操作,所以它要求更大的步骤(一次至少一页,通常是4KB)。当它获得新的空闲块时,分成所请求的大小,其余的放在空闲列表中。

  • OS是控制处理器的MMU(存储器管理单元)的OS。该单元是将当前正在运行的进程看到的线性地址转换为RAM页面的物理地址的单元。这使操作系统具有分配和释放RAM页面到每个进程所需的灵活性。

  • 每个进程都有一个不同的内存映射,允许每个进程“看到”一个线性内存空间,同时保持每个进程与其他进程隔离。操作系统是在每个进程交换机上将映射加载和卸载到MMU的操作系统。将新页面分配给流程最终意味着将其添加到流程的内存映射中。

答案 1 :(得分:0)

  

谁能告诉我更多有关此事的细节?

这些都是高度依赖于操作系统和编译器的细节,我只能提供相当广泛的答案(但你真的不应该担心这个,除非你想进入那个工作领域,疗程)。

  

还记录了哪些其他信息?

通常,freestore内存通常称为“堆”。这基本上是因为它实现为堆,这是一个构建节点树(可用内存块)的优先级队列实现。实际的实现和使用的算法非常复杂,因为它们需要很好地执行(即,在请求新内存时需要非常快速地找到空闲块,并且新释放的内存也必须非常快地合并到堆中)然后,还有所有碎片问题等等。查看Buddy memory allocation上的wiki以获得非常简化的版本。

因此,除了分配的指针列表及其相应的内存块大小之外,还有更多的内容。实际上,可用内存块列表更为重要。

  

这些信息存储在哪里?

Heap是正在运行的程序的一部分(事实上,每个进程,甚至每个加载的模块,都将具有一个或多个这样的结构)。堆不驻留在操作系统中(我甚至不确定它是否需要由操作系统提供,至少不是所有操作系统都提供)。但是,堆显然要求操作系统为其提供大块内存,只要容量被程序的内存请求耗尽,就可以将其整合到其可用内存块树中。

  

删除内存后操作系统会做什么?

通常,当您删除内存时,它只会被添加到空闲(或可用)内存块列表中,并且可能与相邻的空闲内存块(如果存在)合并。没有“用零填充内存”或内存上的任何其他实际操作,这是不必要的,浪费处理时间。