2011-12-11 56 views
1

我有一个简单的C++服务,它从文件中读取文本并通过网络发送它。随着时间的推移,该服务的内存消耗在客户现场增加。在QA测试中没有观察到这种行为。使用WinDbg打印内存对象

我想知道是否有可能在任何给定的时间提取内存中的所有字符串对象。

是否有可能自动执行此过程,以便我可以在不同时间从客户那里获取转储数据,并在每个时间查找内存的大小或内容并比较结果。

回答

1

这听起来像你有内存泄漏。我只使用windbg来调试托管应用程序。也许这个Link可以帮助你一点。

+0

是的朋友,它看起来像只发生在客户环境中的泄漏。感谢链接它有有用的信息。 – Geek

3

对于C++的答案是否定的(在C#是一个不同的故事)。在C++的世界里,如果你怀疑你有泄漏,你可能想在发生“泄漏”之前在进程中启用用户模式堆栈跟踪(gflags.exe中的+ ust)。发生泄漏之后,获得过程转储并检查它。为了检查它(我假设你在这个响应中使用本地窗口堆),你将需要遍历堆结构以找出分配的位置,然后检查堆栈回溯以获取最常见分配大小的抽样。

例子。

  1. 在您运行应用程序之前,运行gflags/i MyApp.exe + ust。这种设置,提供了OS为如何处理过程中MyApp.exe的
  2. 运行程序,让“坏行为”的专项说明发生
  3. 收集过程的转储,而不良行为是很容易的REGKEY看到(越容易看到,越容易将是找到)
  4. 打开转储在WinDbg中
  5. !堆-summary并与拉尔虚拟字节数
  6. 第一colomn是找到堆你的堆处理。使用上一步中找到的条目中的堆句柄并运行heap -stat -h -grp。这将列出使用给定堆中空间最多的堆分配。
  7. 因此,我们现在知道哪个堆很大,并且最常见的条目的大小。我们知道需要一些地址,所以我们可以看看分配给它们的调用堆栈。跑!堆-flt s。
  8. 最后一步(我们很近)。跑!堆-p -a。您现在将拥有堆栈回溯的代码路径生成此分配。现在你可以回到你的代码,并找出为什么这不会被释放。
1
+1

UMDH消耗由+ ust创建的数据。缺点是你必须在目标机器上设置符号。这是我刚抓住转储的主要原因,将其转移到我的工具机器并查看那里的数据。 – JasonE

+0

这是一个棘手的部分,是的 - 同样的事情适用于ETL,你必须有目标机器的二进制副本进行匹配,并且UMDH不记录校验和信息来查找它 –