当前位置: 首页 > 知识库问答 >
问题:

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

居晗日
2023-03-14

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

如果我谈论固定块SM(Github链接),那么我实际上已经看到了它带来的性能优势。在我的例子中,随机大小分配大约提高了40%。

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

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

共有3个答案

靳祺然
2023-03-14

很少需要设计自定义内存管理器。有这么多这样的人在那里,大多数人可以找到一个现成的使用。几年前,我有一个C系统,其中包括一个解释器。在最初的测试中,它没有我们希望的那么快。分析表明,问题在于内存分配,它出现在string类中。我们从互联网上下载了大约24个内存管理器,并依次进行了测试。我们的速度有了很大的提高。我们最终使用的内存管理器总是以2的幂大小分配块,并为每个块大小维护单独的池。

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

费明诚
2023-03-14

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

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

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

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

隗高旻
2023-03-14

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

  1. 更好的调试功能。
    如果有一个内存管理器来帮助定位一些常见的编程错误,例如使用未初始化的内存、访问分配块之外的内存、双重免费、免费后使用,那不是很好吗?但是,一个好的操作系统内存管理器可能已经提供了所有这些功能开箱即用。
  2. 强加内存使用配额。
    在更大的项目中,您可能会担心内存占用,尤其是在使用某些第三方模块的情况下。最好不要让一个流氓模块让所有其他模块挨饿。
  3. 保证分配。
    有时您想确保某个关键html" target="_blank">函数永远不会失败。预先分配一大块内存并提供自定义分配器可能是所需的步骤之一。
  4. 在不受信任的插件之后强制清理内存。
    保护您的应用程序免受与内存占用相同的不健康场景的影响。
  5. 独立系统可能根本没有任何内存管理器.:- )
 类似资料:
  • 问题内容: Java的软件包管理系统对我而言似乎总是简单而有效的。JDK本身大量使用它。我们一直在使用它来模仿名称空间和模块的概念。 什么是 Jigsaw项目 (又名Java平台模块系统)试图填补? 从官方网站: 该项目的目标是为Java SE平台设计和实现标准模块系统,并将该系统应用于平台本身和JDK。 问题答案: Jigsaw和OSGi试图解决相同的问题:如何在保护内部组件的同时允许粗粒度模块

  • easyopen1.4.0开始支持。 创建session 登陆成功后创建session,并返回sessionId // 自定义session @PostMapping("managedSessionLogin") public String managedSessionLogin(HttpServletRequest request) { // 假设登陆成功,创建一

  • 有很多布局管理器,这有点让人不知所措,我不知道使用什么布局管理器来显示bg图像(BackgroundFrame.java)顶部和左侧的左面板(lerframe.java)。我不知道如何进一步描述它,但为了清楚地解释我的困境,我在下面提供了一个说明。 除此之外,我还包括了我的部分代码。 背景框架。Java语言 大型机。Java语言 左撇子rame.java

  • HTTP路由 HTTP路由组件负责将HTTP请求交到对应的函数处理(或者是一个struct的方法),如前面小节所描述的结构图,路由在框架中相当于一个事件处理器,而这个事件包括: 用户请求的路径(path)(例如:/user/123,/article/123),当然还有查询串信息(例如?id=11) HTTP的请求方法(method)(GET、POST、PUT、DELETE、PATCH等) 路由器就

  • 我使用资源管理器模型(新门户)创建了一个Azure存储帐户,现在我想为blob存储配置一个自定义域。文档中说要使用旧门户(对于经典帐户)来实现这一点,但我的存储帐户没有显示在那里(因为它是一个资源管理器帐户,而不是经典帐户)。新门户也没有为我提供设置自定义域的方法;它只是将我指向旧门户上的存储页面。 知道如何为blob存储设置自定义域吗?

  • 本文向大家介绍为什么需要域驱动设计(DDD)?相关面试题,主要包含被问及为什么需要域驱动设计(DDD)?时的应答技巧和注意事项,需要的朋友参考一下 映射领域 降低复杂性 可测试性 可维护性 知识丰富的设计 将业务和服务结合在一起 上下文集中 通用语言