在典型的真实世界的程序中,内存分配/释放有多大的瓶颈?任何类型的程序通常都很重要的答案是受欢迎的.malloc/free/garbage收集的正确实现是否足够快,以至于它只是少数极端情况下的瓶颈,或者大多数性能关键型软件都会从尝试保持内存分配量下降或拥有更快的malloc/free /中获益匪浅垃圾收集实施?
注意:我不是在谈论实时的东西.对性能至关重要,我的意思是吞吐量很重要,但延迟并不一定.
编辑:虽然我提到了malloc,但这个问题不是针对C/C++的.
这很重要,特别是随着碎片的增长,分配器必须更大地搜索您请求的连续区域的更大堆.大多数对性能敏感的应用程序通常会编写自己的固定大小的块分配器(例如,它们一次要求操作系统提供16MB的内存,然后将其分成4kb,16kb的固定块等)以避免此问题.
在游戏中,我看到对malloc()/ free()的调用消耗了高达15%的CPU(写得不好的产品),或者使用精心编写和优化的块分配器,只需5%.鉴于游戏必须具有60赫兹的一致吞吐量,使其停滞500毫秒而垃圾收集器偶尔运行是不切实际的.
几乎每个高性能应用程序现在都必须使用线程来利用并行计算.这是编写C/C++应用程序时真正的内存分配速度杀手所在.
在C或C++应用程序中,malloc/new必须为每个操作锁定全局堆.即使没有争用锁也远非自由,应尽可能避免.
Java和C#在这方面做得更好,因为线程从一开始就被设计,内存分配器在每个线程池中工作.这也可以在C/C++中完成,但它不是自动的.
首先,既然你说了malloc,我假设你在谈论C或C++.
内存分配和释放往往是实际程序的重要瓶颈.当你分配或释放内存时,很多东西都在"引擎盖下",所有这些都是系统特定的; 内存实际上可能被移动或碎片整理,页面可能会被重新组织 - 没有独立于平台的方式来了解其影响.某些系统(如许多游戏控制台)也不进行内存碎片整理,因此在这些系统上,当内存变得支离破碎时,您将开始出现内存不足错误.
一个典型的解决方法是尽可能预先分配尽可能多的内存,并在程序退出之前保持原样.您可以使用该内存来存储大型单片数据集,也可以使用内存池实现以块的形式发送它.出于这个原因,许多C/C++标准库实现会自己执行一定量的内存池.
但是,没有两种方法 - 如果你有一个时间敏感的C/C++程序,那么做大量的内存分配/释放会破坏性能.
通常,在大多数应用程序中,锁争用,算法复杂性或其他性能问题可能使内存分配的成本相形见绌.总的来说,我认为这可能不是我担心的性能问题的前十名.
现在,抓住非常大的内存块可能是一个问题.抓住但不能正常摆脱记忆是我要担心的事情.
在基于Java和JVM的语言中,新的对象现在非常非常非常快.
这是一个体面的文章,由一个知道他的东西的人在底部提供了一些参考资料到更多相关链接:http: //www.ibm.com/developerworks/java/library/j-jtp09275.html
在Java(以及可能具有体面GC实现的其他语言)中分配对象非常便宜.在SUN JVM中,它只需要10个CPU周期.C/c ++中的malloc要贵得多,只是因为它需要做更多的工作.
甚至Java中的分配对象也非常便宜,对于Web应用程序的许多用户而言,这样做仍然会导致性能问题,因为将触发更多的垃圾收集器运行.因此,由于GC的重新分配导致Java中的分配存在间接成本.这些成本难以量化,因为它们非常依赖于您的设置(您拥有多少内存)和您的应用程序.