【发布时间】:2014-09-09 19:06:27
【问题描述】:
我想检查进程的本机堆以查看内存中存在哪些本机类以及它们的大小。它相当于 sos !dumpheap -stat 命令。是否可以在原生端做到这一点?
【问题讨论】:
标签: c++ windbg crash-dumps
我想检查进程的本机堆以查看内存中存在哪些本机类以及它们的大小。它相当于 sos !dumpheap -stat 命令。是否可以在原生端做到这一点?
【问题讨论】:
标签: c++ windbg crash-dumps
简短的回答是否定的。您可以查看堆并查看已分配块的大小,但本机代码的基本事实之一是您不能依赖它来将类型标签放入已分配的对象中,因此堆上的对象通常不包含足够的信息来确定其类型。
当您处理诸如 Windows GDI 堆(它确实将类型标记放入分配的对象)之类的东西时,您可以这样做,但对于仅分配和使用内存的其他代码,您需要的信息只是没有'不存在。
我可能应该补充一点:如果您有调试信息(并且不太关心执行速度),则可能可以跟踪分配和分配它们的类型,因此您可以从分配的块向后工作内存到实际的对象类型。一些堆调试工具已经完成了至少与此类似的事情,尽管我不知道有什么工具完全符合您的要求。
【讨论】:
我猜您想要检查本机堆的原因是分析堆使用情况,并可能找出堆上分配的性质以及代码的哪一部分对此负责。如果是这样,umdh 工具的输出是我能想到的最接近的。它比!dumpheap -stat 详细得多,但您可以从中获得更多信息——例如您可以通过查看分配调用堆栈来确定负责分配的确切代码。
通常 Umdh 用于内存泄漏诊断。要获得进程中所有分配的细分,您需要使用所谓的单转储模式。
虽然 Umdh 的输出不会直接告诉您分配的本机类型是什么,但在大多数情况下,您可以轻松地从分配调用堆栈中派生它。例如,在 Umdh 输出的这个 sn-p 中,有 0x4a 分配,总共消耗 0x194b0 字节,并且分配类型很容易弄清楚,因为 std::vector<unsinged short> 在调用堆栈中,并且分配是在方法 RecordData 中完成的: :反序列化。
+ 194b0 ( 194b0 - 0) 4a allocs BackTraceD0F18F8
+ 4a ( 4a - 0) BackTraceD0F18F8 allocations
ntdll!RtlAllocateHeap+36991
MSVCR120D!_heap_alloc_base+51 (f:\dd\vctools\crt\crtw32\heap\malloc.c, 58)
MSVCR120D!_heap_alloc_dbg_impl+1FF (f:\dd\vctools\crt\crtw32\misc\dbgheap.c, 431)
MSVCR120D!_nh_malloc_dbg_impl+1D (f:\dd\vctools\crt\crtw32\misc\dbgheap.c, 239)
MSVCR120D!_nh_malloc_dbg+2A (f:\dd\vctools\crt\crtw32\misc\dbgheap.c, 302)
MSVCR120D!malloc+19 (f:\dd\vctools\crt\crtw32\misc\dbgmalloc.c, 56)
MSVCR120D!operator new+F (f:\dd\vctools\crt\crtw32\heap\new.cpp, 59)
STestViewer!std::_Allocate<unsigned short>+2F (c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0, 28)
STestViewer!std::allocator<unsigned short>::allocate+19 (c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0, 578)
STestViewer!std::_Wrap_alloc<std::allocator<unsigned short> >::allocate+1A (c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0, 848)
STestViewer!std::vector<unsigned short,std::allocator<unsigned short> >::_Reallocate+57 (c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector, 1588)
STestViewer!std::vector<unsigned short,std::allocator<unsigned short> >::_Reserve+5A (c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector, 1619)
TestViewer!std::vector<unsigned short,std::allocator<unsigned short> >::resize+FC (c:\program files (x86)\microsoft visual studio 12.0\vc\include\vector, 1136)
TestViewer!RecordData::Deserialize+52 (c:\src\stcommonlib\stdmodel.cpp, 174)
TestViewer!SensorDrModel::LoadFromFile+21E (c:\src\stcommonlib\stsmodel.cpp, 50)
在其他情况下,对象的类型在调用堆栈中并不明显,但由于您有调用operator new 的源文件名和行号,您可以通过查看源代码来确定。
总结你从 Umdh 中得到了什么:
【讨论】: