繁体   English   中英

为什么要设计自定义内存管理器?

[英]Why design custom memory manager?

我过去设计过简单的固定块存储管理器(SM) 和通用内存管理器 在这两种情况下,我都会在启动时分配一大块堆内存,并一次又一次地重新使用已释放的内存,从而防止频繁调用昂贵的malloc/new调用。

如果我谈论固定块 SMGithub 链接) ,那么我实际上已经看到了它带来的性能优势。 就我而言,随机大小分配大约有 40% 的改进。

但是对于通用内存管理器Github 链接)(没有内存池),我没有看到任何明显的性能提升。 我能看到的唯一收获是访问内存使用情况统计信息。 性能方面,由于确定空闲块(分配期间)和映射中的内存位置(释放期间)的开销,它变得更慢。

所以我的问题是,在什么情况下自定义通用内存分配器会有用? 值得付出努力吗?

性能并不是开发自定义分配器的唯一原因。 其他原因可能包括:

  1. 更好的调试能力
    有一个内存管理器可以帮助定位一些常见的编程错误,比如使用未初始化的内存、访问分配块之外的内存、双重释放、释放后使用,难道不是很好吗? 然而,一个好的操作系统内存管理器可能已经提供了所有这些开箱即用的功能。
  2. 强加内存使用配额
    在较大的项目中,您可能会担心内存占用,尤其是在使用某些第三方模块时。 最好不要让流氓模块让所有其他模块饿死。
  3. 保证分配
    有时您想确保某个关键功能永远不会失败。 预分配一大块内存并提供自定义分配器可能是所需的步骤之一。
  4. 不受信任的插件后强制内存清理
    保护您的应用程序免受与内存占用完全相同的不健康场景的影响。
  5. 独立系统可能根本没有任何内存管理器。 :-)

通常,构建自定义分配器的最大动机与性能无关。 相反,需要在各种系统上运行的程序会遇到不一致和/或不完整的库。 特别是标准库。 此外,嵌入式系统的硬件限制经常要求应用程序在内存使用和管理方面非常小心。 这些程序运行从汽车中的空调到飞机上的自动驾驶仪的所有内容。 还有一些系统没有需要仔细管理堆的堆栈。 这些例子只是冰山一角。 将它与一个基本的分配器结合起来,就像许多基于堆栈的设计之一,你会得到一个非常容易编写、易于维护和高性能的解决方案。 编写自己的分配器的另一个原因很简单,就是内存不足。 当有大量“空闲”内存但没有足够大的块来填充请求时,通常会出现这种情况。 这意味着内存在分配器中变得碎片化。 以谷歌“facebook 内存分配器”为例。

所有这些程序中的一个共同主题是需要解决方案特定的内存管理器。 这就是有这么多免费可用的管理器的原因。 如果没有特殊需要,那么就没有充分的理由使用 malloc/new 以外的任何东西。 或者,甚至更好地制定需要使用智能指针来处理幕后内存分配的策略。 使用外部工具可以轻松完成内存分析和统计,这通常是程序员迈向解决方案特定内存管理器的第一步。 您永远不应该从“通用内存管理器”开始,然后再问“我为什么要使用它”。

最后,您使用的术语“存储管理器”是指更广泛的一类工具,它们通常管理从短期内存到长期存储和归档的数据。 这些工具更为罕见,可能非常复杂,而且是需要用于特定需求(例如数据库)的解决方案特定工具。

性能通常是在程序中包含内存管理器的最后一个原因,也就是说,如果内存管理器的性能不能超过系统至少 2 倍,那么就会出现严重错误。 要么是程序找到了管理器的退化案例,要么是管理器本身存在需要解决的问题。

很少需要设计自定义内存管理器。 市面上有很多这样的产品,大多数人都可以找到一个现成的使用。 几年前,我有一个包含解释器的 C++ 系统。 在最初的测试中,它并没有我们希望的那么快。 分析显示问题出在内存分配上,它出现在字符串类中。我们从互联网上下载了大约两打内存管理器,并依次尝试了其中的每一个。 我们能够大幅提高速度。 我们最终使用的内存管理器始终使用大小为 2 的幂的分配块,并为每个块大小维护单独的池。

我们发现了比我们可能测试的更多的内存管理器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM