Memory 虚拟地址空间碎片

Memory 虚拟地址空间碎片,memory,windbg,virtual-memory,Memory,Windbg,Virtual Memory,我正在调查虚拟地址空间碎片。我遇到的问题是对VirtualAlloc的调用可能有很多源(LOH、内存映射等) 我可以从转储文件中识别函数的调用方吗?想知道我的问题的根源吗?首先,必须为操作系统组件和程序设置pdb符号:在符号路径窗口中设置如下字符串 srv*f:\symbols\websymbols*http://msdl.microsoft.com/download/symbols 并将路径添加到程序专用符号。 执行此操作后,可以在命令kb上看到prety堆栈跟踪。堆栈中程序的第一个出现是调用

我正在调查虚拟地址空间碎片。我遇到的问题是对
VirtualAlloc
的调用可能有很多源(LOH、内存映射等)


我可以从转储文件中识别函数的调用方吗?想知道我的问题的根源吗?

首先,必须为操作系统组件和程序设置pdb符号:在符号路径窗口中设置如下字符串

srv*f:\symbols\websymbols*http://msdl.microsoft.com/download/symbols

并将路径添加到程序专用符号。
执行此操作后,可以在命令kb上看到prety堆栈跟踪。堆栈中程序的第一个出现是调用方函数。

首先,必须为操作系统组件和程序设置pdb符号:在符号路径窗口中设置如下字符串

srv*f:\symbols\websymbols*http://msdl.microsoft.com/download/symbols

并将路径添加到程序专用符号。
执行此操作后,可以在命令kb上看到prety堆栈跟踪。堆栈中程序的第一个出现是调用方函数。

您必须为应用程序启用gflags用户堆栈跟踪,您可以从命令行或WinDbg中执行此操作,如果从WinDbg:

!gflag +ust
然后你需要做一个
!堆-s
!heap-stat-hxx
对于给定的heapblock,我建议在这里执行内存转储
。dump/ma c:\first.dmp
然后执行导致碎片的操作,按
ctrl+break
返回WinDbg并输入
!再次堆-s
,然后执行另一个内存转储
.dump/ma c:\second.dmp

内存转储和堆摘要的原因是,您可以分析哪些堆正在增加或返回,打开转储并对这些快照执行分析,将结果转储到文本文件并对结果进行区分

因此,如果您确定了一个正在增加的特定堆块,那么您可以转储该块的每个分配
!heap-p-a xxxx
其中xxxx是您的堆块,我建议您设置WinDbg将输出写入一个文件,因为这将非常大
。logfile c:\first.txt
在第二个内存转储上重复,并进行区分以查看发生了哪些额外的分配

您还可以转储堆的统计信息,这将为您提供分配大小的细分,这也可能为您提供线索。无论如何,只要您有带有专用符号的PDB,那么您就可以通过完整的调用堆栈来识别谁进行了分配

编辑

有一篇文章可以帮助您:

如果您可以获得虚拟地址,则可以使用
转储其他信息!pte地址
pfn frameNum
您可以从
的结果中获取虚拟地址的页面帧编号!pte


!vm 1
将显示虚拟内存使用情况的一些统计信息,但不会显示更多,另一件事是您可以在调用
virtualAlloc
时设置一个断点,并转储调用堆栈和本地变量如果您使用
kf
,则这将显示堆栈帧之间的字节距离,这可能表示分配量较大,我会将此信息写入日志文件,稍后在两个转储之间进行比较。

您必须为您的应用程序启用gflags用户堆栈跟踪,您可以从命令行或WinDbg中执行此操作,如果来自WinDbg:

!gflag +ust
然后你需要做一个
!堆-s
!heap-stat-hxx
对于给定的heapblock,我建议在这里执行内存转储
。dump/ma c:\first.dmp
然后执行导致碎片的操作,按
ctrl+break
返回WinDbg并输入
!再次堆-s
,然后执行另一个内存转储
.dump/ma c:\second.dmp

内存转储和堆摘要的原因是,您可以分析哪些堆正在增加或返回,打开转储并对这些快照执行分析,将结果转储到文本文件并对结果进行区分

因此,如果您确定了一个正在增加的特定堆块,那么您可以转储该块的每个分配
!heap-p-a xxxx
其中xxxx是您的堆块,我建议您设置WinDbg将输出写入一个文件,因为这将非常大
。logfile c:\first.txt
在第二个内存转储上重复,并进行区分以查看发生了哪些额外的分配

您还可以转储堆的统计信息,这将为您提供分配大小的细分,这也可能为您提供线索。无论如何,只要您有带有专用符号的PDB,那么您就可以通过完整的调用堆栈来识别谁进行了分配

编辑

有一篇文章可以帮助您:

如果您可以获得虚拟地址,则可以使用
转储其他信息!pte地址
pfn frameNum
您可以从
的结果中获取虚拟地址的页面帧编号!pte


!vm 1
将显示虚拟内存使用情况的一些统计信息,但不会显示更多,另一件事是您可以在调用
virtualAlloc
时设置一个断点,并转储调用堆栈和本地变量如果您使用
kf
,则这将显示堆栈帧之间的字节距离,这可能表示分配量较大,我会将此信息写入日志文件,稍后在两个转储之间进行比较。

转储文件对此没有帮助。itI需要完全内存转储。我没有的是虚拟内存块和分配该块的stacktrace之间的关系。转储文件对此没有帮助。itI需要完全内存转储。我没有的是虚拟内存块和分配该块的堆栈跟踪之间的关系