zoukankan      html  css  js  c++  java
  • 在VMMap中跟踪不可用的虚拟内存

    VMMap是一个很好的系统内部工具,它可以可视化特定进程的虚拟内存,并帮助理解内存的用途。它有线程堆栈、映像、Win32堆和GC堆的特定报告。有时,VMMap会报告不可用的虚拟内存,这与可用内存不同。下面是32位进程(总共有2GB虚拟内存)的VMMap报告示例:

    这种“不可用”的内存从何而来,为什么不能使用?Windows虚拟内存管理器具有64KB的分配粒度。当直接用VirtualAlloc分配内存并要求小于64KB(比如16KB)时,VirtualAlloc返回64KB边界上的地址。然后分配前四页(16KB),其余48KB标记为未使用。无法通过执行另一个分配来获取此内存,因为VirtualAlloc将始终返回驻留在64KB边界上的地址。那么,这个内存是不可用的。
    VMMap中的fragmentation视图使问题更加明显。在下面的屏幕截图中,黄点是4KB区域,可以分配和使用,而灰色矩形是60KB区域,不能使用。当整个地址空间都是这些不可用的区域时,你得到的虚拟内存就没有你想象的那么多了。

    幸运的是,很容易找到违规分配的来源。本质上,我们正在寻找分配大小小于64KB(或者更好:不能被64KB平均整除)的VirtualAlloc调用。您可以使用VMMap本身(它具有跟踪模式)跟踪这些分配,也可以附加WinDbg并设置断点:

    0:000> bm kernelbase!VirtualAlloc* "r $t0 = poi(@esp+8); .if (@$t0 % 0x10000 != 0) { .printf "Unusable memory will emerge after allocating %d bytes", @$t0; kb 4 } .else { gc }"
      1: 76c03e8a          @!"KERNELBASE!VirtualAllocExNuma"
      2: 76bcd532          @!"KERNELBASE!VirtualAlloc"
      3: 76c03e66          @!"KERNELBASE!VirtualAllocEx"
    0:000> g
    Unusable memory will emerge after allocating 4096 bytes
    ChildEBP RetAddr  Args to Child              
    00defd48 010a4e34 00000000 00001000 00003000 KERNELBASE!VirtualAlloc
    00defe2c 010a5f25 00000000 00000000 7eaa7000 FourKBLeak!allocate_small+0x34
    00deff18 010a6989 00000001 012ba870 012bae98 FourKBLeak!main+0x35
    00deff68 010a6b7d 00deff7c 7529919f 7eaa7000 FourKBLeak!__tmainCRTStartup+0x199

    此断点确保传递给VirtualAlloc的分配大小可被64KB整除。否则,断点将停止并打印出有问题的分配和调用堆栈;否则,它将继续执行。这将使捕获小分配的源变得非常容易,并有望修复它们。

  • 相关阅读:
    Qt画笔实现折线图
    Qt动态布局
    ffmpeg录制流媒体,正常方式停止录制
    解决libvlc_media_player_stop时死锁的方法
    Ubuntu 16 修改时区!
    qt窗口最小化之后无法打开
    Qt 之 去除窗口部件被选中后的焦点虚线框
    WINDOWS中, 如何查看一个运行中的程序是64位还是32位的
    DHTMLX学习总结
    mui plus.uploader.createUpload 上传文件服务端获取文件名中文乱码问题
  • 原文地址:https://www.cnblogs.com/yilang/p/12033563.html
Copyright © 2011-2022 走看看