根据我的理解,如果对象小于缓存行大小,内存池应该可以提高通常一起访问的对象的缓存性能 - 因为相邻的对象可能会同时被提取到缓存中。
但是对于大于缓存行大小的对象呢?将这些数据汇集到同一内存区域有什么好处吗?
(假设分配/解除分配时间无关紧要,我担心的是访问权限......)
谢谢!
答案 0 :(得分:6)
使用池的一个重要原因是它们使分配方案比通用分配器简单得多。由于所有对象都具有相同的大小,因此没有碎片,您只需要维护一个空闲列表。对于新的分配,您尝试弹出空闲列表的顶部,或者如果列表为空,则增加高水印,完成。 (您可以在池内存本身的O(1)空间中实现空闲列表。)
但是,池的使用是高度情境化的,并且是否有任何好处在很大程度上取决于您的实际代码路径和分配要求。现代标准分配器已经非常好用许多短期固定大小的分配,所以你真的需要分析和检查。
答案 1 :(得分:1)
如果您的应用使用巨大内存量并开始交换,内存池是有意义的。然后,如果对象彼此相邻,它们将被一起分页。
答案 2 :(得分:0)
我之前的项目是一个嵌入式应用程序,内置了ARM SAM9x平台的Web服务器。它只有64K堆,并且没有任何控制台/显示器或文件系统,因此无法将 printf()错误发送到 stderr 或将其记录到文件中。尽管如此,它必须工作7/24它不应该停止“内存不足”错误,必须运行没有错误。如果它开始一次,它永远不会停止。内存不足不是可恢复的错误,它是系统的完全失败。
所以,我决定不使用 new 。我已经使用过对象数组:ringbuffers,固定大小的池等等 - 它只是起作用。 Java(和C#等)让我们错了,这些现代语言说,记忆是一个大海洋,任何人都可以从中汲取。是的,这是真的,如果你有足够的,但成本很高,就像你在这篇文章中提到的那样。
试试吧!尽可能少用 new (和 malloc())。一个很好的副作用:你不必使用 delete (以及 free()),不存在内存泄漏问题。