4

我试图找到一个显着的内存泄漏(一次 15MB,但在多个地方进行这样的分配)。我检查了最明显的地方,然后使用了 AQTime,但我仍然无法确定它。现在我看到剩下 2 个选项:

1)使用SetProcessWorkingSetSize:我已经尝试过了,但是当使用超过150MB时,我的进程很高兴地继续运行:

DWORD MemorySize = 150*1024*1024;
SetProcessWorkingSetSize( GetCurrentProcess(), MemorySize/2, MemorySize*2 );

2) 一次分配超过 1MB 时设置断点。我应该怎么做,重载 operator new,里面有一个 'if>1MB' ?

4

6 回答 6

1

SetProcessWorkingSetSize 并不意味着您认为它意味着什么 - 它是操作系统关于“在内存中”保留多少内存而不是分页到磁盘的线索。现代操作系统在将未使用的内存分页到磁盘时非常激进 - Windows 尤其如此。

除了非常彻底的代码分析之外,IBM Rational Purify是您唯一的解决方案。在 Windows 上,对于 C/C++,没有更好的工具来查找内存泄漏。在 Mac 或 Linux 上,您可以使用 valgrind,但 AFAIK,它还不能在 Windows 上运行。

于 2010-04-12T17:06:01.340 回答
1

从您的标签中,您正在使用 c++ 和 Visual Studio。

在这种情况下,您可以简单地使用 Microsoft 为您提供的 crt 调试挂钩。

在 msdn 中搜索 _CrtSetAllocHook。

在调试版本中,这将允许您拦截每个分配 - 您可以忽略小的分配,只需设置一个断点或在大的分配上调用 ::DebugBreak。

于 2010-04-12T21:57:47.657 回答
0

1)使用SetProcessWorkingSetSize:我已经尝试过了,但是当使用超过150MB时,我的进程很高兴地继续运行:

SetProcessWorkingSetSize 返回什么?通话成功了吗?

2) 一次分配超过 1MB 时设置断点。我应该怎么做,重载 operator new,里面有一个 'if>1MB' ?
是的,这应该有效。

检查 MSVC 提供的C 运行时调试堆提供的工具可能会有所帮助。

于 2010-04-12T17:08:40.243 回答
0

在嵌入式类型系统上,我们将完全按照您的建议进行操作 - 将任何对 new/memAlloc 的调用置于某个阈值之上,并对 free/delete 执行相同操作。乏味,但它会完成工作。大小上的条件断点应该可以满足您的要求,但是在删除时,情况会更糟。

于 2010-04-12T17:10:40.487 回答
0

尝试使用UMDH。它是一个免费的 Microsoft 实用程序,允许查找内存泄漏。

于 2010-04-12T17:15:14.843 回答
0

对不起,所有建议的解决方案都没有奏效。最终使用 AQTime 和大量调试输出修复了它。泄漏在关机时得到了清理,因此它正在大海捞针。

尽管如此,我仍然对如何有效地找到它感兴趣。我试图在 new 运算符上放置一个条件断点,但调试器需要很长时间来评估每个分配的“字节 > 1024 * 1024”。

于 2010-04-16T23:09:30.873 回答