内存分配/释放瓶颈?

52

在典型的现实世界程序中,内存分配/释放有多大瓶颈?欢迎回答任何需要考虑性能的程序类型。像malloc/free/垃圾收集等良好实现是否足够快,以至于只有在少数情况下才会成为瓶颈,或者大多数性能关键软件从尽量减少内存分配量或拥有更快的malloc/free/垃圾收集实现中获益显著?

注意:这里不涉及实时内容。通过输出吞吐量来衡量性能的东西,但延迟不一定重要。

编辑:尽管提到了malloc,但本问题并不是特定于C/C++。

12个回答

1

如果你谈论的是 Microsoft 堆,大部分人都是的。同步处理和内存碎片化都很容易解决。

目前首选的堆是 LFH(碎片堆),这是 Vista+ 操作系统的默认设置,并且可以在 XP 上通过 gflag 进行配置,非常容易。

使用 LFH 堆可以轻松避免任何锁定、阻塞、争用和总线带宽等问题。

HEAP_NO_SERIALIZE

在HeapAlloc或HeapCreate期间使用HEAP_NO_SERIALIZE选项。这将允许您创建/使用堆而不进入交错等待。

我建议使用HeapCreate创建几个堆,并定义一个宏,例如mallocx(enum my_heaps_set,size_t);

当然,如果您想要得到更好的效果,还需要设置realloc和free。如果您想变得更加高级,请使free/realloc自动检测堆句柄,通过评估指针的地址来识别哪个堆句柄,甚至添加一些逻辑,以允许malloc根据其线程ID识别要使用的堆,并构建每个线程堆和共享全局堆/池的层次结构。

Heap* API由malloc/new在内部调用。

这是一篇关于一些动态内存管理问题的不错文章,其中包含一些更好的参考资料。用于检测和分析堆活动。


LFH交易分配速度以获得低碎片化,所以我们不可能完全错误... - peterchen

0

其他人已经涵盖了C/C++,所以我只会在.NET上添加一些信息。

在.NET中,堆分配通常非常快,因为它只是在堆的零代部分获取内存。显然,这不能永远进行下去,这就是垃圾回收的作用。垃圾回收可能会显著影响应用程序的性能,因为用户线程必须在内存压缩期间暂停。全面收集越少,越好。

在.NET中,有各种各样的事情可以影响垃圾收集器的工作量。通常,如果您有很多内存引用,垃圾收集器将不得不做更多的工作。例如,通过使用邻接矩阵而不是节点之间的引用来实现图形,垃圾收集器将不得不分析较少的引用。

无论这在您的应用程序中是否真正重要取决于几个因素,您应该使用实际数据对应用程序进行分析,然后再考虑这样的优化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接