windbg中的外部碎片和虚拟地址碎片

时间:2014-01-23 07:21:29

标签: windbg

我正在使用windbg来调试Win7上的内存问题。

我使用!heap -s并得到以下输出。

0:002> !heap -s
LFH Key                   : 0x6573276f
Termination on corruption : ENABLED
  Heap     Flags   Reserv  Commit  Virt   Free  List   UCR  Virt  Lock  Fast 
                    (k)     (k)    (k)     (k) length      blocks cont. heap 
-----------------------------------------------------------------------------
000f0000 00000002    1024    552   1024    257     7     1    0      0   LFH
00010000 00008000      64      4     64      2     1     1    0      0      
00330000 00001002    1088    160   1088      5     2     2    0      0   LFH
00460000 00001002     256      4    256      2     1     1    0      0      
012c0000 00001002    1088    408   1088      8    10     2    0      0   LFH
00440000 00001002    1088    188   1088     24     9     2    0      0   LFH
01990000 00001002    1088    188   1088     24     9     2    0      0   LFH
00420000 00001002    1088    152   1088      5     2     2    0      0   LFH
01d20000 00001002      64     12     64      3     2     1    0      0      
01c80000 00001002      64     12     64      1     2     1    0      0      
012e0000 00001002  776448 118128 776448 109939   746   532    0      0   LFH
    External fragmentation  93 % (746 free blocks)
    Virtual address fragmentation  84 % (532 uncommited ranges)
01900000 00001002     256      4    256      1     1     1    0      0      
01fa0000 00001002     256    108    256     58     3     1    0      0      
01c40000 00001002      64     16     64      4     1     1    0      0      
03140000 00001002      64     12     64      3     2     1    0      0      
33f40000 00001002      64      4     64      2     1     1    0      0      
340f0000 00001002    1088    164   1088      3     5     2    0      0   LFH
-----------------------------------------------------------------------------

我的问题是什么是外部碎片,什么是虚拟地址碎片? 93%和84%是什么意思?

提前谢谢。

3 个答案:

答案 0 :(得分:6)

WinDbg的输出是指碎片编号之前的堆,在您的情况下是堆012e0000

External fragmentation = 1 - (larget free block / total free size)

这意味着该堆中最大的空闲块为7.63 MB,但总可用空间大小为109 MB。这通常意味着您不能一次在该堆中分配超过7.63 MB的数据。

有关外部碎片的详细说明,另请参阅Wikipedia

Virtual address fragmentation: 1 - (commit size / virtual size)

虽然我没有找到虚拟内存碎片的好解释,但这是对公式的解释:虚拟大小是总可用内存。提交大小是使用的。差异(1 - x)无法使用。

您可以使用!heap -f -stat -h <heap>(在您的情况下为!heap -f -stat -h 012e0000)详细了解该堆。

答案 1 :(得分:0)

如果您正在尝试调试内存碎片问题,则应该查看sysinternals中的VMMAP。

http://technet.microsoft.com/en-us/sysinternals/dd535533

您不仅可以看到最大空闲块的确切大小,还可以访问其中的“碎片视图”,以查看内存碎片的可视化显示。

答案 2 :(得分:0)

感谢Stas Sh的回答。

我正在使用VMMap来分析进程使用的内存。

但我对VMMap中显示的私人数据感到困惑。

我编写了一个演示应用程序,并使用HeapCreate创建一个私有堆,然后通过HeapAlloc从该堆中分配大量小块。

我使用VMMap来分析这个演示应用程序,并且关注来自VMMap的信息。

Process: HeapOS.exe
PID: 2320

Type         Size        Committed  Private   Total WS  Private WS  Shareable WS  Shared WS  Locked WS  Blocks  Largest   
Total        928,388     806,452    779,360   782,544   779,144     3,400         2,720                 188     
Heap         1,600       500        488       460       452         8             8                     13      1,024
Private Data 888,224     774,016    774,016   774,016   774,012     4             4                     24      294,912

我发现堆非常小,但私有数据非常大。

但是从VMMap的帮助中,它解释了

Private

Private memory is memory allocated by VirtualAlloc and not suballocated either by the Heap Manager or the .NET run time. 
It cannot be shared with other processes, is charged against the system commit limit, and typically contains application data. 

所以我猜私有数据是VirtualAlloc从进程的虚拟地址空间分配的内存,而不能与其他进程共享。私有数据可以通过app代码分配,也可以由OS的Heap Manager或.NET运行时分配。

相关问题