Rit*_*esh 7 c c++ memory memory-management
我已经看到很多代码库特别是服务器代码有基本的(有时是高级的)内存管理器.内存管理器的真正目的是减少malloc调用的次数,还是主要用于内存分析,损坏检查或可能是其他以应用程序为中心的目的.
保存malloc调用的参数是否足够合理,因为malloc本身就是一个内存管理器.我可以理解的唯一性能增益是当我们知道系统总是要求相同大小的内存时.
或者拥有内存管理器的原因是free不会将内存返回给操作系统但会保存在列表中.因此,在进程的生命周期中,如果由于碎片而继续执行malloc/free,则进程的堆使用可能会增加.
malloc是一个通用的分配器 - "不慢"比"总是快"更重要.
考虑一个在许多常见情况下可以提高10%的功能,但在少数情况下可能会导致性能显着下降.特定于应用程序的分配器可以避免罕见情况并获得好处.通用分配器不应该.
除了对malloc的调用次数外,还有其他相关属性:
分配的位置
在当前的硬件上,这很容易成为性能的最重要因素.应用程序具有更多访问模式的知识,并可以相应地优化分配.
多线程
通用分配器必须允许调用malloc并从不同的线程中释放.这通常需要锁定或类似的并发处理.如果堆非常繁忙,则会导致大量争用.
知道某些高频alloc/frees只来自一个线程的应用程序可以使用自己的特定于线程的堆,这不仅可以避免对这些分配的争用,还可以增加它们的局部性并减轻默认分配器的负担.
碎片
对于物理内存或地址空间有限的系统上长时间运行的应用程序,这仍然是一个问题.即使没有实际工作集增加,碎片也可能需要来自OS的越来越多的内存或地址空间.对于需要不间断运行的应用程序来说,这是一个重大问题.
上次我更深入地研究分配器(可能是过去的五年),人们一致认为,减少碎片的天真尝试往往与永不缓慢的规则相冲突.
同样,知道(某些)分配模式的应用程序可能会从默认分配器中承担大量负载.一个非常常见的用例是构建一个语法树或类似的东西:有大量的小分配,它们从不单独释放,只作为一个整体.这种模式可以通过非常简单的分配器有效地提供.
重要性和诊断
最后,默认分配器的诊断和自我保护功能可能不足以满足许多应用程序的需求.
为什么我们有自定义内存管理器而不是内置内存管理器?
第一个原因可能是代码库最初是在 20-30 年前编写的,当时提供的代码并不好,没有人敢更改它。
但除此之外,正如您所说,因为应用程序需要管理碎片,在启动时获取内存以确保内存始终可用,出于安全性或其他原因 - 其中大部分可以通过正确使用内置函数来实现经理。