您知道如何使用gflag和+ust来获得与每个分配配对的调用堆栈。然后你可以在windbg中使用!heap来诊断泄漏?
我想在通过VirtualAlloc分配大量资源的情况下这样做。据我所知,VirtualAlloc会绕过gflag/!堆扩展吗?
我希望有人能证实
a)!堆遍历每个堆中已分配内存的列表-但不遍历来自VirtualAlloc的已分配内存
b)当您通过新的/malloc分配一个巨大的内存块时,它会先转到LocalAlloc(),然后转到VirtualAlloc(),它会绕过调用堆栈日志记录
我真的希望有人能帮助我调试这种泄漏。如果分配的空间小一点,我使用堆就没问题了
发布于 2011-05-15 10:08:18
您可以尝试LeakDiag,它可以在许多不同类型的内存上运行,包括源自VirtualAlloc的内存。
发布于 2011-05-26 03:07:59
堆函数在比Virtual*函数更高的级别上操作;实际上,堆必须调用VirtualAlloc才能向进程地址空间添加更多内存。对于Virtual*调用,!heap不会帮你。
发布于 2017-02-24 03:13:03
背景
操作系统仅通过VirtualAlloc()提供内存。这可以很好地工作,但粒度不好:它一次只能提供64kB。这就是为什么微软实现了不同的堆管理器,例如C++堆管理器或.NET堆管理器。它们以64kB块的形式从操作系统获取内存,并以较小的块形式将其提供给C++或.NET程序。
!heap和相关命令仅适用于C++堆管理器。要检查.NET堆,您需要WinDbg的sos扩展。
关于你的问题
据我所知,
会绕过gflag/!堆扩展吗?
GFlags +ust标志特定于C++堆分配。!heap命令也是特定于C++堆管理器的,所以是的,这些命令都不关心VirtualAlloc()调用。
然而,我不会说VirtualAlloc()“绕过”它们,这将是一个声明,它通过C++堆管理器。恰恰相反:它位于比堆管理器操作更低的级别。
遍历每个堆中已分配内存的列表,但不遍历来自VirtualAlloc的已分配内存
是的,出于同样的原因。
b)当您通过转到LocalAlloc()然后转到VirtualAlloc()的新/malloc分配了大量内存时,它会绕过调用堆栈日志记录
基本上是这样的。在某一时刻,将内存划分为更小的区域不再值得。显然,为一个2字节的变量分配64kB太浪费了。
微软在HeapAlloc中记录的大约512 kB (查找术语0x7FFF8)中绘制了这条线。因此,当您分配超过512个kB时,它将不再使用堆管理器,而是使用VirtualAlloc()的原始内存块。在最坏的情况下,有12%的开销(当你分配512kB +1Byte时,64KB的浪费)。
别担心
还有其他工具可以识别由VirtualAlloc()引起的更大的内存泄漏。WinDbg命令!address很有帮助,Rohitab API monitor也可以提供帮助。正如其他人所建议的,您也可以尝试使用LeakDiag或商业内存泄漏分析器。
https://stackoverflow.com/questions/6005568
复制相似问题