C ++中的堆行为

时间:2010-06-01 19:34:29

标签: c++ optimization heap

优化全局运算符new的优化是否有任何问题将所有分配都集中到下一个2的幂?从理论上讲,这可以降低碎片,但代价是更高的最坏情况内存消耗,但操作系统是否已经采用这种技术的冗余行为,或者它是否尽力节省内存?

基本上,考虑到内存使用不是性能问题,我应该这样做吗?

4 个答案:

答案 0 :(得分:6)

默认的内存分配器可能非常智能,可以很好地处理大量的中小型对象,因为这是最常见的情况。对于所有分配器,请求的字节数永远不会是分配的数量。例如,如果你说:

char * p = new char[3];

分配器几乎肯定会做类似的事情:

char * p = new char[16];   // or some minimum power of 2 block size

除非您能证明您的分配存在实际问题,否则您不应考虑编写自己的新版本。

答案 1 :(得分:4)

你应该尝试实现它以获得乐趣。一旦它起作用,就扔掉它。

答案 2 :(得分:3)

你应该这样做吗?没有。

有两个原因:

  • 重载全局新运算符将不可避免地给您带来痛苦,尤其是当外部库依赖于库存版本时。
  • 堆的现代OS实现已经考虑了碎片。如果您使用的是Windows,如果您有特殊需要,可以查看“Low Fragmentation Heap”。

总结一下,除非你能证明(通过剖析)它是一个问题,否则不要乱用它。不要过早优化。

答案 3 :(得分:0)

我同意Neil,Alienfluid和Fredoverflow的观点,在大多数情况下你不想编写自己的内存分配器,但我仍然编写了自己的内存分配器大约15年并且多年来对它进行了改进(第一个版本是使用malloc /免费重新定义,使用全局新/删除操作符的更高版本),根据我的经验,优势可能是巨大的:

  • 可以在应用程序中构建内存泄漏跟踪。无需运行会降低应用程序速度的外部应用程序。
  • 如果您实施不同的策略,有时您会发现只需切换到不同的内存分配策略的难题
  • 要查找与内存相关的难题,您可以轻松地将记录添加到内存分配器中,甚至可以进一步优化它(例如,记录大小为N字节的内存的所有新闻和删除)
  • 您可以使用页面分配策略,您可以在其中分配完整的4KB页面并设置页面大小,以便立即捕获缓冲区溢出
  • 如果内存被释放两次,您可以添加要删除的逻辑以打印出
  • 很容易将红色区域添加到内存分配(分配内存之前的校验和和分配内存之后的校验和)以更快地找到缓冲区溢出/下溢
  • ...