C ++内存分配机制性能比较(tcmalloc vs. jemalloc)

我有一个应用程序分配大量的内存,我正在考虑使用比malloc更好的内存分配机制。

我的主要选项是:jemalloc和tcmalloc。 使用其中的任何一个有什么好处?

在http://locklessinc.com/benchmarks.shtml中有一些机制(包括作者的专有机制 – lockless)之间有很好的比较,并且提到了每个机制的优点和缺点。

鉴于这两种机制都是积极的,并不断改进。 有没有人有任何关于这两个相对performance的洞察力或经验?

Solutions Collecting From Web of "C ++内存分配机制性能比较(tcmalloc vs. jemalloc)"

如果我没有记错,主要区别是多线程项目。

两个库都试图通过让线程从不同的缓存中获取内存来获得去争用内存,但是他们有不同的策略:

  • jemalloc (由Facebook使用)维护每个线程缓存
  • tcmalloc (来自Google)维护一个缓存池,线程为缓存产生“自然”亲和力,但可能会改变

如果我没有记错的话,这再一次导致了线程管理的一个重要区别。

  • 如果线程是静态的, jemalloc速度更快,例如使用池
  • 线程创建/销毁时, tcmalloc速度更快

还有一个问题,因为jemalloc旋转新的缓存来容纳新的线程id,突然出现的线程会在随后的平静阶段留下(大部分)空的缓存。

因此,我会在一般情况下推荐使用tcmalloc ,并保留jemalloc用于非常特定的用法(应用程序生命周期中的线程数量变化很小)。

我最近在工作中考虑了tcmalloc。 这是我观察到的:

  • 在多线程设置中,大量改进了大量使用malloc的性能。 我在工作中使用了它,性能几乎提高了两倍。 原因是在这个工具中有一些线程在关键循环中执行小对象的分配。 使用glibc,性能受到影响,我认为,锁定不同线程中的malloc / free调用之间的争用。

  • 不幸的是,tcmalloc增加了内存占用。 我上面提到的工具会消耗两倍或三倍以上的内存(以最大驻留集大小衡量)。 由于我们实际上正在寻找减少内存占用的方法,增加的占用空间对我们来说是不行的。

最后,我决定不使用tcmalloc,而是直接优化应用程序代码:这意味着从内部循环中删除分配,以避免malloc / free锁争用。 (好奇,使用压缩的形式,而不是使用内存池。)

对您的教训是,您应该仔细衡量您的应用与典型的工作量。 如果你能承受更多的内存使用,tcmalloc可能对你很好。 如果不是,那么通过避免频繁调用线程间内存分配,tcmalloc仍然可以看到你将获得什么。

你也可以考虑使用Boehm保守的垃圾收集器 。 基本上,你用GC_malloc (等等)替换你的源代码中的每一个malloc ,你不用打扰free 。 Boehm的GC不会比malloc更快地分配内存(大概是相同的,或者可能会减慢30%),但它有自动处理无用内存区域的优势,这可能会改善您的程序(当然,因为你不关心免费)。

如果你真的认为malloc太慢了,而且如果你完全理解你的程序的分配行为,你可以用你的特殊分配器来替换一些malloc -s(例如,可以使用mmap从大内存中获取内存的内存并自己管理内存)。 但我相信这样做是一种痛苦。

正如其他人所建议的那样,如果您认为malloc是一个瓶颈,您可以分块(或使用arenas)或数组中分配数据。

有时候,实现一个专门的复制垃圾收集器 (对于你的一些数据)可能会有所帮助。

但不要忘记, 过早的优化是邪恶的 ,请基准和配置您的应用程序,以准确地了解时间丢失。

请注意,根据“nedmalloc”主页,现代操作系统的分配器现在实际上非常快:

“Windows 7,Linux 3.x,FreeBSD 8,Mac OS X 10.6都包含最先进的分配器,没有任何第三方分配器可能会在现实世界的结果中显着改善它们”

http://www.nedprod.com/programs/portable/nedmalloc

所以你可能能逃脱只是推荐你的用户升级或类似的东西:)

你的帖子不提到线程,但是在考虑混合使用C和C ++的分配方法之前,我会研究一下内存池的概念.BOOST有一个很好的例子。