内存管理 - C++ 中的自定义分配器有什么问题?

memory management - what's wrong with custom allocator in C++?

本文关键字:分配器 什么 问题 自定义 管理 C++ 内存      更新时间:2023-10-16
Bjarne Stroustrup在他的著作《C++编程语言》中说:

建议:在编写自己的分配器之前三思而后行

Bjarne通过给出上述建议想说什么?如果我编写自己的分配器,会出现哪些问题?这真的有问题吗?我应该如何克服这些问题?

我和两位同事Ben Zorn和Kathryn McKinley(现在都在微软研究院(一起写了一篇关于这一点的论文(Reconciding Custom Memory Allocation,OOPSLA 2002(。它获得了最具影响力论文奖——以下是引文。

自定义内存管理通常用于系统软件中,目的是降低分配成本并严格控制软件的内存占用。直到2002年,人们还理所当然地认为特定于应用程序的内存分配器优于通用库。Berger、Zorn和McKinley的论文通过一项严格的实证研究证明了这一假设没有充分的依据,并深入探讨了通用分配器优于手工分配器的原因。该论文也因其实证方法论的质量而引人注目。

最初的论文实际上比引文做得更多:这是论文的摘要。所指的Lea分配器构成了Linux分配器的基础。

希望实现性能改进的程序员通常使用自定义内存分配器。这项深入的研究考察了八个使用自定义分配器的应用程序。令人惊讶的是,对于其中六个应用程序,最先进的通用分配器(Lea分配器(的性能与自定义分配器一样好或更好。这两个例外使用的区域提供了更高的性能(提高了44%(。区域还减少了程序员的负担,消除了内存泄漏的根源。然而,我们表明,程序员无法释放区域内的单个对象可能会导致内存消耗的大幅增加。更糟糕的是,这种限制排除了对常见编程习惯用法使用区域,从而降低了它们的有用性。

我们提出了一个通用的和基于区域的分配器的概括,我们称之为reaps。Reap是区域和堆的组合,通过添加单个对象删除,提供了全方位的区域语义。我们展示了reaps的实现提供了高性能,优于其他具有类似区域语义的分配器。然后,我们用一个案例研究来证明reaps在实践中的空间优势和软件工程优势。我们的结果表明,需要快速区域的程序员应该使用reap,而大多数考虑自定义分配器的程序员应该改为使用Lea分配器。

我们最近做了一项后续研究,发现在几个现代应用程序上几乎有完全相同的效果:自定义分配器通常会减慢应用程序的速度

除了滚动自己的自定义内存分配器通常意味着性能和空间受到影响之外,它还使调试变得更加困难,并意味着你无法驾驭通用分配器的改进浪潮——包括系统提供的分配器和其他分配器,如Hoard和tcmalloc。