C++ 如何实现内存堆
我不确定标题的措辞,但问题是: 我听说过程序员在程序开始时分配一大块连续内存,然后根据需要进行处理。这与每次需要内存时都直接进入操作系统形成对比。 我听说这会更快,因为它可以避免不断向操作系统请求连续内存块的成本 我相信JVM就是这样做的,维护自己的内存部分,然后从中分配对象C++ 如何实现内存堆,c++,c,memory,heap,allocation,C++,C,Memory,Heap,Allocation,我不确定标题的措辞,但问题是: 我听说过程序员在程序开始时分配一大块连续内存,然后根据需要进行处理。这与每次需要内存时都直接进入操作系统形成对比。 我听说这会更快,因为它可以避免不断向操作系统请求连续内存块的成本 我相信JVM就是这样做的,维护自己的内存部分,然后从中分配对象 我的问题是,如何真正实现这一点?在程序开始时分配足够大的内存块以满足其需要。然后,您必须重写new和/或malloc、delete和/或free以将内存从/返回到该缓冲区 在实现这种解决方案时,您需要编写自己的分配器(从块
我的问题是,如何真正实现这一点?在程序开始时分配足够大的内存块以满足其需要。然后,您必须重写new和/或malloc、delete和/或free以将内存从/返回到该缓冲区 在实现这种解决方案时,您需要编写自己的分配器(从块中获取源代码),最终可能会使用多个分配器,这就是您首先分配内存池的原因
默认内存分配器是一个很好的全能分配器,但不是所有分配需求的最佳分配器。例如,如果您知道您将为特定大小分配大量对象,则可以定义分配固定大小缓冲区并预先分配多个以获得一定效率的分配器。 < P>大多数C和C++编译器已经提供堆内存管理器作为标准库的一部分,因此,您根本不需要做任何事情来避免每个请求都影响操作系统 如果您想提高性能,有许多改进的分配器,您可以简单地链接并使用它们。e、 例如,在一个现在被删除的答案中提到了哪些wheaties(实际上很好——wheaties,你为什么要删除它?) 如果您想编写自己的堆管理器作为学习练习,以下是它需要做的基本事情:
- 从操作系统请求一大块内存
- 保留空闲块的链接列表
- 当收到分配请求时:
- 在列表中搜索一个块,该块足够大,可以容纳所请求的大小,还可以存储一些簿记变量
- 为当前请求分割足够大的块,将剩余的块放回空闲列表中
- 如果没有足够大的块,请返回操作系统并请求另一个大块
- 当解除分配请求传入时
- 阅读标题以了解大小
- 将新释放的块添加到空闲列表中
- 或者,查看紧跟其后的内存是否也列在空闲列表中,并将两个相邻的块合并成一个更大的块(称为合并堆)
- 这是经典的分配器,也是非多线程使用的最佳分配器之一:
你可以从阅读它的设计说明中学到很多东西。文章中的
malloc.c
链接已损坏;现在可以在网站上找到它
话虽如此,除非您的程序有真正不寻常的分配模式,否则编写自己的分配器或使用自定义分配器可能是一个非常糟糕的主意。特别是如果您试图更换系统malloc
,您可能会遇到来自不同库(或标准库函数)的各种错误和兼容性问题,从而链接到“错误版本的malloc
”
如果您发现自己只需要为一些特定的任务分配专门的资源,那么这可以在不替换malloc
的情况下完成。我建议在GNUobstack
和对象池中查找固定大小的对象。这些涵盖了专业分配可能具有实际用途的大多数情况
IBMdeveloperWorks有一篇关于内存管理的好文章,其中包含大量参考资料部分供进一步阅读: 维基百科也有一些很好的信息:,。你说的“进入操作系统”是什么意思?堆完全在用户模式下实现,除非需要分配更多的页面,否则每次堆分配都不需要系统调用。或者你在想一些不同的东西吗?问题“我如何实现内存管理器”很好,但是你必须确保你真的需要它。如果你这样做是为了训练或只是为了好玩-好的。如果你确实知道内存分配是程序中的一个瓶颈,你应该首先考虑重新设计你的程序,以便它分配更大的块。只有在完成这项工作后,才应该使用自己的内存管理器。Ou