你知道如何使用gflags wih + ust来获得与每个分配配对的调用堆栈。你可以在windbg中使用!heap来诊断泄漏吗?
我希望通过VirtualAlloc进行大量分配。据我所知,VirtualAlloc会绕过gflags /!heap扩展名吗?
我希望有人可以确认
a)!heap遍历每个堆中已分配内存的列表 - 但不是来自VirtualAlloc的已分配内存
b)当你通过new / malloc分配一大块内存时,它会转到LocalAlloc()然后再转移到VirtualAlloc(),它会绕过调用堆栈记录
我真的希望有人能协助我调试这种泄漏。如果分配较小,我就没有问题!堆
答案 0 :(得分:2)
您可以尝试使用LeakDiag,它可以处理许多不同类型的内存,包括来自VirtualAlloc的内存。
答案 1 :(得分:1)
堆函数的运行级别高于Virtual*
函数;实际上,堆必须调用VirtualAlloc以向进程地址空间添加更多内存。 !heap
无法通过Virtual*
来电帮助您。
答案 2 :(得分:1)
操作系统仅通过VirtualAlloc()提供内存。这工作正常,但粒度不好:它一次只能提供64kB。这就是微软实施不同堆管理器的原因,例如C ++堆管理器或.NET堆管理器。那些从64kB块的OS中获取内存,并以较小的块提供给C ++或.NET程序。
!heap
和相关命令仅适用于C ++堆管理器。要检查.NET堆,需要WinDbg的sos扩展名。
据我所知,VirtualAlloc会绕过gflags /!heap扩展名吗?
GFlags +ust
标志特定于C ++堆分配。 !heap
命令也特定于C ++堆管理器,所以是的,这些命令都不关心VirtualAlloc()调用。
但是,我不会说,VirtualAlloc()会“绕过”它们,这将是它通过C ++堆管理器的声明。它恰恰相反:它比堆管理器运行的级别更低。
a)!heap遍历每个堆中已分配内存的列表 - 但不是来自VirtualAlloc的已分配内存
是的,出于同样的原因。
b)当你通过new / malloc分配一大块内存时,它会转到LocalAlloc()然后再转移到VirtualAlloc(),它会绕过调用堆栈记录
基本上是的。有一点是不再值得将内存分成更小的区域。显然,为2字节变量分配64kB太浪费了。
微软将这条线设为~512 kB,如HeapAlloc中所述(寻找术语0x7FFF8)。因此,当您分配超过512 kB时,它将不再使用堆管理器,而是使用VirtualAlloc()的原始内存块。在最坏的情况下,有12%的开销(当你分配512kB + 1字节时浪费64kB)。
还有其他工具可以识别VirtualAlloc()引起的更大内存泄漏。 WinDbg命令!address
很有帮助,Rohitab API monitor可以提供帮助。正如其他人所建议的那样,您也可以尝试使用LeakDiag或商用内存泄漏分析仪。