简体   繁体   English

虚拟地址空间碎片

[英]Virtual Address Space Fragmentation

I am investigating a virtual address space fragmentation. 我正在研究虚拟地址空间碎片。 The problem I have is that the calls to VirtualAlloc can have many sources (LOH, Memory mappings, ...) 我的问题是对VirtualAlloc的调用可以有许多来源(LOH,内存映射等)

Can I identify the caller of the function from a dump file ? 我可以从转储文件中识别函数的调用者吗? of figure out somehow the source of my problem ? 弄清楚我问题的根源?

You must enable gflags user stack trace for you app, you can do this from the command line or within WinDbg, if from WinDbg: 您必须为您的应用启用gflags用户堆栈跟踪,您可以从命令行或在WinDbg(如果是WinDbg)中执行以下操作:

!gflag +ust

then you need to do a !heap -s and !heap -stat -h XX for a given heapblock will dump more specific stats , I suggest performing a memory dump here .dump /ma c:\\first.dmp then do the thing that is causing the fragmentation, break back into WinDbg by pressing ctrl+break and enter !heap -s again and perform another memory dump .dump /ma c:\\second.dmp . 那么对于给定的!heap -stat -h XX您需要执行!heap -s!heap -stat -h XX将转储更多特定的统计信息,我建议在此处执行内存转储.dump /ma c:\\first.dmp然后执行该操作导致碎片,请按ctrl+break break重新进入WinDbg,然后再次输入!heap -s并执行另一个内存转储.dump /ma c:\\second.dmp

The reason for the memory dumps and the heap summaries is that you can analyse which heaps are increasing or go back, open the dumps and perform analysis on those snapshots, dump the results into a text file and do a diff on the results. 内存转储和堆摘要的原因是,您可以分析正在增加或返回的堆,打开转储并对这些快照进行分析,将结果转储到文本文件中,并对结果进行比较。

So if you identified a particular heap block that is increasing then you can dump every allocation for that block !heap -p -a xxxx where xxxx is your heap block, I suggest you setup WinDbg to write the output to a file as this will be very large .logfile c:\\first.txt repeat on the second memory dump and do a diff to see what additional allocations are occurring. 因此,如果您发现一个正在增加的特定堆块,那么您可以转储该块的每个分配!heap -p -a xxxx其中xxxx是您的堆块,建议您设置WinDbg将输出写入文件,因为这将是非常大的.logfile c:\\first.txt在第二个内存转储上重复,并进行比较以查看发生了哪些其他分配。

Also you can dump the stats for the heap which will give you a breakdown of allocation sizes and this may also give you a clue. 另外,您可以转储堆的统计信息,这将使您获得分配大小的详细信息,这也可能会为您提供线索。 Anyway so long as you have the pdbs with the private symbols then you can identify who made the allocation with full call stacks. 无论如何,只要您的pdb带有专用符号,您就可以确定谁使用完整的调用堆栈进行了分配。

Edit 编辑

There is an article which may help you: http://bugslasher.net/2011/01/15/memory-exhaustion-even-if-a-large-enough-free-memory-segment-is-available/ 有一篇文章可能会对您有所帮助: http : //bugslasher.net/2011/01/15/memory-exhaustion-even-if-a-large-enough-free-memory-segment-is-available/

If you can get the virtual addresses then you can dump additional information using !pte address and pfn frameNum you can get the page frame number for the virtual address can be obtained from the result from !pte . 如果可以获取虚拟地址,则可以使用!pte addresspfn frameNum转储其他信息,您可以获取虚拟地址的页面框架号,该页号可以从!pte的结果中获取。

!vm 1 will display some stats on your virtual memory usage but not much more, the other thing is you could put a breakpoint on calls to virtualAlloc and dump the call stack and local variables if you use kf then this will display the distance in bytes between the stack frames which may indicate large allocations, I would write this information out to a log file and compare it later between the 2 dumps. !vm 1将显示有关虚拟内存使用情况的一些统计信息,但不多得多,另一件事是,您可以在对virtualAlloc的调用上设置断点,并转储调用堆栈和局部变量(如果使用kf则将以字节为单位显示距离在可能表示分配量很大的堆栈帧之间,我会将这些信息写到日志文件中,然后在两个转储之间进行比较。

First, you must set pdb symbols for OS components and your programm : In symbols path window set string like this 首先,必须为OS组件和程序设置pdb符号:在符号路径窗口中设置如下字符串

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

and add path to your program private symbols. 并添加程序私有符号的路径。 After this action you can see prety stack trace on command kb. 完成此操作后,您可以在命令kb上看到诱饵堆栈跟踪。 First occurence of your programm in stack is caller function. 程序在堆栈中的首次出现是调用程序功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM