【问题标题】:external fragmentation and virtual address fragmentation in windbgWindbg中的外部碎片和虚拟地址碎片
【发布时间】:2014-01-23 07:21:28
【问题描述】:

我正在使用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% 是什么意思?

提前谢谢你。

【问题讨论】:

  • 这里有人熟悉这个吗?

标签: windbg


【解决方案1】:

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)了解有关该堆的更多详细信息。

【讨论】:

  • 你能解释一下你怎么知道最大的空闲块是7.63MB吗?虚拟大小是什么意思?在我的情况下,Virt 总是等于 Reserv。
  • @KevinTian:最大空闲块可以通过求解最大空闲块的公式来计算。 Largest free block = (1 - external fragmentation) * total free size.
  • @KevinTian:一种区分物理内存,可以被Windows使用(内核模式)和虚拟内存,可以被应用程序使用(用户模式)。只要不做驱动开发,memory就是virtual memory的简称。 WinDbg 还在我的机器上显示相同的 Virt 和 Reserv 值。可能是WinDbg 6.2的bug,我之前也有不同的值。
【解决方案2】:

如果您尝试调试内存碎片问题,您应该查看来自 sysinternals 的 VMMAP。

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

您不仅可以在那里看到最大空闲块的确切大小,还可以进入其中的“碎片视图”,以直观地展示您的内存碎片化程度。

【讨论】:

    【解决方案3】:

    感谢 Stas Sh 的回答。

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

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

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

    我使用VMMap来分析这个demo app,以下信息来自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
    

    我发现 Heap 很小,但 Private Data 很大。

    但是从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. 
    

    所以我猜 Private Data 是 VirtualAlloc 从进程的虚拟地址空间分配的内存,不能与其他进程共享。私有数据可以由应用程序代码分配,也可以由操作系统的堆管理器或.NET 运行时分配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-09
      • 2015-12-21
      • 2010-11-15
      • 2017-01-29
      • 2015-03-23
      • 2017-12-09
      • 1970-01-01
      • 2012-11-19
      相关资源
      最近更新 更多