防止内存碎片化的新“-delete技巧”

4

我记得在一本关于电脑游戏编程的书中读到过,很抱歉我不记得书名了。书中提到,提高性能的简单方法是在开始时执行以下操作:

int main()
{
 {
   char dummy* = new char[10000000];  // 10Mbytes ish
   delete[] dummy;
 }
 ...
}

这个想法是动态内存分配中昂贵的部分是从操作系统获取内存的请求,通常直到程序结束才会返回。有人使用过这个方法并看到了性能提升吗?


3
好的,但是与内存碎片化有什么关系呢? :) - ypnos
1
好像是放置 new / 内存池?如果我错了请纠正我。 - DumbCoder
2
一个聪明的编译器不会自动“删除”那些无用的语句吗? - ereOn
@DumbCoder:不,他不使用块进行分配,他立即释放它。 - sharptooth
@sharptooth - 哦,我没看到那个。如果编译器被欺骗以提高性能,我会感到惊讶。但是,如果有人在实践中证明了这一点,我应该相信它。 - DumbCoder
4个回答

4

这是否可行取决于所涉及的操作系统。许多现代操作系统在处理大内存分配时使用 mmap 并直接绕过进程堆。这意味着分配将直接从操作系统中进行,然后在释放时直接返回给操作系统。

一个更好的策略是通常在开始时进行内存分配,并尽可能地重复使用已分配的空间,在将内存返回到堆之前尽可能长时间地使用它。这就是 STL 分配器背后的逻辑。


不要相信你所读的一切,这就是这个故事的寓意! - Chris Huang-Leaver

3

这没有意义。你分配了一个巨大的块,然后释放它,堆接管了该块占用的内存,并且在稍后使用时可以合法地对其进行碎片化。


1

这并不一定会提高性能,因为当前的标准没有说明内存是如何动态分配、释放和重新分配的。然而,实现可以在程序的其余部分中使用相同的内存区域,每当它需要分配内存时。这更像是内存池。

任何事情都有可能发生。这完全取决于实现。此外,它甚至可以选择删除代码,因为它什么也不做。


1

根据您的环境,可能有加载器标志可让您指定初始堆大小。 当您的程序加载到内存中时,将分配此内存,因此它成为启动时间的一部分。 这应该会产生相同的结果,并带来编译器不会优化它的好处。


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