首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何实现内存堆

如何实现内存堆
EN

Stack Overflow用户
提问于 2010-12-21 11:21:42
回答 5查看 12K关注 0票数 23

我不太确定该如何表达这个标题,但问题是:

我听说过程序员在程序开始时分配一大块连续的内存,然后根据需要进行处理。这与每次需要内存时简单地转到操作系统中形成了对比。我听说这会更快,因为它可以避免不断地向操作系统请求连续的内存块的成本。

我相信JVM就是这样做的,它维护自己的内存段,然后从中分配对象。

我的问题是,如何真正实现这一点?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-12-21 11:37:31

大多数C和C++编译器已经提供了堆内存管理器作为标准库的一部分,所以您根本不需要做任何事情,以避免每次请求都会影响到操作系统。

如果你想提高性能,有许多改进的分配器,你可以简单地连接起来就走。例如Hoard,wheaties在现在删除的答案中提到了它(这实际上是很好的- wheaties,你为什么要删除它?)

如果您想编写自己的堆管理器作为学习练习,下面是它需要做的基本事情:

  • 从操作系统请求一个大的内存块
  • 当一个分配请求进入时,保留一个空闲块的链接表
    • 在列表中搜索一个足以满足请求大小的块,并在当前请求的块的足够大的块之外存储一些记账变量,将其余的放回空闲表

    < chunk

>H112>如果没有足够大的块,请返回操作系统并请求另一个大块

  • 当释放请求到来时,读取头以找出大小
    • 将新释放的块添加到空闲块上查看紧随其后的内存是否也在空闲表中列出,并将两个相邻的块合并为一个更大的块(称为合并list
    • optionally,

票数 18
EN

Stack Overflow用户

发布于 2010-12-21 11:28:52

您可以在程序开始时分配足够大的内存块来支持它的需求。然后,您必须覆盖new和/或malloc,删除和/或释放以将内存返回到此缓冲区。

在实现这种解决方案时,您需要编写自己的分配器(以块为源),并且最终可能会使用多个分配器,这通常是您首先分配内存池的原因。

默认内存分配器是一个很好的全方位分配器,但并不是最适合所有的分配需求。例如,如果您知道将为特定大小分配大量对象,则可以定义一个分配器来分配固定大小的缓冲区,并预先分配多个缓冲区以提高效率。

票数 7
EN

Stack Overflow用户

发布于 2010-12-21 12:25:42

下面是经典的分配器,也是最适合非多线程使用的分配器之一:

http://gee.cs.oswego.edu/dl/html/malloc.html

你可以从它的设计说明中学到很多东西。文章中指向malloc.c的链接已损坏;现在可以在http://gee.cs.oswego.edu/pub/misc/malloc.c上找到它。

也就是说,除非你的程序真的有不寻常的分配模式,否则编写自己的分配器或使用定制的分配器可能是一个非常糟糕的主意。特别是如果你试图替换系统malloc,你可能会冒着来自不同库(或标准库函数)的各种bug和兼容性问题链接到“错误版本的malloc”的风险。

如果您发现自己只需要为几个特定的任务进行专门的分配,则无需替换malloc即可完成。我建议在GNU obstack和对象池中查找固定大小的对象。这些涵盖了大多数情况,在这些情况下,专门分配可能具有真正的实际用处。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4495990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档