C ++(窗口)中的分配号码及其预测性

我正在使用_CrtDumpMemoryLeaks来识别我们的软件中的内存泄漏。 我们在multithreading应用程序中使用第三方库。 这个库确实有内存泄漏,因此在我们的testing中,我们要识别那些我们没有任何控制权的内容。

我们使用持续集成,所以新的function/algorithm/错误修复一直在增加。

所以问题是 – 是否有一个安全的方法来识别那些是我们的泄漏和那些是第三方库。 我们虽然关于使用分配号码,但是安全吗?

Solutions Collecting From Web of "C ++(窗口)中的分配号码及其预测性"

您可能需要使用Microsoft提供的DebugDiag工具。 有关该工具的完整信息,请参阅: http : //www.microsoft.com/en-sg/download/details.aspx?id=40336

DebugDiag可以用来识别各种问题。 我们可以按照步骤来追踪泄漏(我们的和第三方模块):

  1. 在规则类型“本机(非.NET)内存和处理泄漏”下配置DebugDiag。
  2. 现在重新运行应用程序并捕获转储文件。 我们还可以配置DebugDiag以在指定的时间间隔后捕获转储文件。
  3. 现在我们可以使用“性能分析器”下的DebugDiag打开/分析捕获的转储文件。

一旦分析完成,DebugDiag会自动生成报告,并给你的模块/ DLL信息泄漏是可能的(概率)。 之后,我们从DebugDiag工具中获取有关模块的信息,我们可以通过静态代码分析来专注于特定的模块。 如果模块属于第三方DLL,我们可以共享DebugDiag报告给他们。 除此之外,如果使用适当的PDB文件运行/附加你的应用程序,DebugDiag也提供了可能发生内存泄漏的地方的调用栈。

过去,在基于Windows的应用程序上调试内存泄漏时,这些信息非常有用。 希望以上信息将是有用的。

在一个大的应用程序中,我工作在全局的newdelete操作符被覆盖(例如,看如何正确地替换全局new和delete操作符 )和使用私有堆(例如HeapCreate )。 第三方库将使用进程堆,因此分配将明确分开。

坦率地说,我不认为你可以得到更多的分配数量。 对应用程序/库使用明确的单独堆(甚至可能在您自己的应用程序中有单独的每个组件堆)将更易于管理。 考虑到你可以添加自己的应用程序特定的头到每个分配的块,从而启用非常花哨的内存跟踪。 例如捕获分配整个调用堆栈将是可能的,用于调试。 启用每个组件会计。 等等

答案真的取决于第三部分图书馆的实际执行情况。 它是否只泄露了一致的项目数量,或者是否依赖于线程的数量,库中使用的函数等? 什么时候分配?

即使如此,如果这是一个一致数量的泄漏,不管库的使用情况如何,我会犹豫是否使用这个分配号码。 通过一切手段,试试看。 如果所有的分配都是在很早的时候完成的,并且不依赖于任何“你的”代码,那么它就可以工作 – 这是一件非常简单的事情。 但尝试添加例如static std::vector<int>(100)以查看静态变量中的内存分配是否影响分配数量…如果是这样,这个方法可能注定要失败(除非你有非常严格的规则静态对象)。

使用一个单独的堆(替换新的/删除操作符)将是正确的解决方案,因为这可能会扩展到收集其他统计信息(如分配数量,以检测部分代码过度分配 – 当然,这必须根据代码实际进行分析]。

较新的Doug Lea malloc包括mspace抽象。 一个mspace是一个单独的堆。 在我们的几个100K NCSL应用程序中,我们为代码的不同部分使用了十几个不同的mspace。 我们使用分配器让STL容器从正确的空间分配内存。

一些好处

  • 第三方代码不使用mspaces,所以他们的分配(和泄漏)不与我们混合
  • 我们可以看一下每个mspace的内存使用情况,看看哪一段代码可能有内存泄漏
  • 任何内存损坏都包含在一个空间内,从而限制了我们需要查看的调试代码量。

您可能可以使用Mirosoft的堆调试库来执行此操作,而无需使用任何第三方解决方案。 根据我从上一个问题得知的内容,您应该确保代码中分配的所有内存都是通过调用_malloc_dbg进行分配的,其中第二个参数设置为_CLIENT_BLOCK 。 然后,您可以使用_CrtSetDumpClient设置回调函数,该回调将只接收有关已分配的客户端块的信息,而不是其他回调函数。

您可以轻松使用预处理器将所有调用转换为mallocfree实际调用其调试版本(例如_malloc_dbg ); 看看它是如何在Visual Studio附带的crtdbg.h中完成的。

对我来说,棘手的部分将是搞清楚如何覆盖newdelete操作来调用像_malloc_dbg这样的调试功能。 在自己的代码中只有new的和delete受到影响,而不是在第三方库中找到解决方案可能很难。