Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 内存泄漏如何提高性能_C++_Performance_Memory Leaks - Fatal编程技术网

C++ 内存泄漏如何提高性能

C++ 内存泄漏如何提高性能,c++,performance,memory-leaks,C++,Performance,Memory Leaks,我正在构建一个充满节点的大型RTree(空间索引)。它需要能够处理许多查询和更新。对象不断地被创建和销毁。我正在运行的基本测试是,随着树中对象数量的增加,查看树的性能。我插入100-20000个大小均匀、随机分布的对象,增量为100。搜索和更新与我目前面临的问题无关 现在,当没有内存泄漏时,“插入树”性能无处不在。它的运行时间从10.5秒(15000个对象)到1.5秒(18000个对象)。没有任何模式 当我故意添加一个漏洞时,就像添加“new int”一样简单;我不会将它分配给任何东西,因为它本

我正在构建一个充满节点的大型RTree(空间索引)。它需要能够处理许多查询和更新。对象不断地被创建和销毁。我正在运行的基本测试是,随着树中对象数量的增加,查看树的性能。我插入100-20000个大小均匀、随机分布的对象,增量为100。搜索和更新与我目前面临的问题无关

现在,当没有内存泄漏时,“插入树”性能无处不在。它的运行时间从10.5秒(15000个对象)到1.5秒(18000个对象)。没有任何模式

当我故意添加一个漏洞时,就像添加“new int”一样简单;我不会将它分配给任何东西,因为它本身有一条直线,性能会立即下降到一条非常柔和的曲线上,从100个对象的0(大致)秒倾斜到整个20k的1.5秒

在这一点上非常非常失落。如果你想要源代码,我可以包括它,但它是huuuggeee,字面上唯一有区别的一行是“newint

提前谢谢!
-尼克

我不确定你是如何想出这个新的int测试的,但这并不是解决问题的好方法:)使用分析器运行你的代码,找出真正的延迟在哪里。然后集中精力解决热点问题


g++内置了它-只需使用
-pg

编译就可以解释这一点(理论)

  • 编译器没有删除空的新int
  • 新int位于一个内部循环中,或者在递归遍历中的某个位置,在该位置执行的时间最长
  • 进程的总RSS会增加,最终会增加进程使用的总内存
  • 因此会出现页面错误
  • 由于页面错误,进程将成为I/O绑定,而不是CPU绑定 最终结果是吞吐量下降。如果您能提及正在使用的编译器以及用于构建代码的编译器选项,这将有所帮助

  • 没有更多的信息就不可能确定

    然而,我想知道这是否与堆碎片有关。通过创建一个释放多个内存块的程序,您很可能会创建一个连接在一起的小内存块的整个负载。内存管理器需要跟踪所有这些内存块,以便在需要时可以再次分配它们

    当您释放一个块时,一些内存管理器尝试将其与周围的内存块“合并”,在高度碎片化的堆上,这可能非常缓慢,因为它试图找到周围的块。不仅如此,如果您的物理内存有限,它可以“接触”内存的许多物理页面,因为它遵循内存块链,这可能会导致整个负载极慢的页面错误,这将在速度上非常不稳定,具体取决于操作系统决定为该进程提供多少物理内存

    通过保留一些未释放的内存,您将改变这种访问模式,这可能会对速度产生很大影响。例如,您可能会强制运行时库每次分配新的内存块,而不必跟踪大小合适的现有块以重用


    我没有证据表明您的程序中存在这种情况,但我知道当执行大量新的和空闲的程序时,内存碎片通常是导致程序运行缓慢的原因。

    解决方案:不要从Visual Studio运行。实际运行.exe文件。我明白了这一点,因为这就是剖析器正在做的事情,数字正在神奇地下降。检查内存使用情况和运行的版本(并给我例外的时间)没有膨胀到过大的大小


    Visual Studio为什么会做这种荒谬的事情的解决方案:没有线索。

    我在这里暗中摸索,但问题可能是堆碎片化的方式。你说你正在创造一个毁灭大量物体的世界。我将假设这些对象都具有不同的大小

    当在堆上分配内存时,所需大小的单元将从堆中断开。释放内存后,该单元格将添加到可用列表中。当执行新的alloc时,分配器遍历堆,直到找到足够大的单元。当执行大量分配时,空闲列表可能会变得相当长,遍历列表可能需要相当长的时间

    现在int相当小。因此,当您执行新的int时,它可能会耗尽空闲列表中所有的小堆单元,从而显著加快较大的分配


    但是,您可能正在分配和释放大小类似的对象。如果您使用自己的自由列表,您将可以保护自己的许多堆行走,并可能显著提高性能。这正是STL分配器为提高性能所做的工作。

    您可能需要简化测试代码-出现了一些奇怪的情况,由于测试的复杂性,您可能看不到这一点。试着用一个更简单的数据结构运行一个类似的测试,然后从那里开始。在我看来,你的问题似乎在别处,以及性能与
    新int之间的关系大多是偶然的。您确定
    新建int生存优化?是的。通过了装配,你得到了一个数量级的减速?没有什么比简单地暂停一下,看看它在做什么更容易看出问题所在。这就是我和我交谈过的人一直倾向的。VisualStudio2005编译器。所有选项:/O2/GL/D“WIN32”/D“NDEBUG”/D“_CONSOLE”/D“_UNICODE”/D“UNICODE”/FD/EHsc/MD/fp:fast/Yu“stdafx.h”/fp“Release\DestinyTest.pch”/Fo“Release\\\\\”/FD“Release\vc80.pdb”/W3/nologo/c/Wp64/Zi/TP/errorReport:promptI同意如果更改最多。。。假设运行时间的25%