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整除。否则,断点将停止并打印出有问题的分配和调用堆栈;否则,它将继续执行。这将使捕获小分配的源变得非常容易,并有望修复它们。

在VMMap中跟踪不可用的虚拟内存的更多相关文章

  1. AnsiString 在 Delphi 中虽然不可用,但是,在 C++ 中可以用

    [C++] C++ Builder 中 Ansi 编码的字符串在Android/iOS程序中显示的问题 呃,这个问题说起来,其实也不麻烦,C++ Builder 本身在 TEncoding 做了处理, ...

  2. 获取Windows系统中的所有可用和在用串口

    目的:获取Windows系统中的所有可用和在用串口 方法:注册表查询法 优点:简单.实用.快速.无遗漏,无多余结果. 说明:另外还有8种方法可以枚举串口,但都不如此法. 代码和详细注释如下: //-- ...

  3. windows 32位系统中进程最大可用内存空间为3GB (转)

    http://msdn.microsoft.com/zh-cn/library/ms189334.aspx 进程地址空间 所有 32 位应用程序都有 4 GB 的进程地址空间(32 位地址最多可以映射 ...

  4. SQL2005 : 如何在SQL Server Profiler (事件查看器)中 跟踪查看死锁恢复

    SQL Profiler 通过 SQL Profiler 工具程序,可监控应用程序如何访问数据库引擎.普通来说,当系统性能需要优化或是应用程序对数据库访问的结果不合预期,都可以使用该工具确认视图问题所 ...

  5. 教程:在 VM Depot 中查找 Azure 可用的虚拟机镜像

     发布于 2014-07-08 作者 陈 忠岳 对于 Azure 的社区管理虚拟机资源库--VM Depot--的用户来说,网站的搜索功能已得到极大的改善.这一搜索能力的增强,可以帮助用户更容易地 ...

  6. VB6/VBA中跟踪鼠标移出窗体控件事件(类模块成员函数指针CHooker类应用)

    一.关于起因 前几天发了一篇博文,是关于获取VB类模块成员函数指针的内容(http://www.cnblogs.com/alexywt/p/5880993.html):今天我就发一下我的应用实例. V ...

  7. 在linux系统中跟踪高IO等待

    原文作者:Jon Buys 原文地址:http://ostatic.com/blog/tracking-down-high-io-wait-in-linux 译者:Younger Liu,本作品采用知 ...

  8. C# WebApi 中设置Session可用

    在Global.acax中,添加下面方法 //设置session可用 public override void Init() { PostAuthenticateRequest += MvcAppli ...

  9. OpenStack中MySQL高可用配置

    采用Heartbeat+DRBD+mysql高可用方案,配置两个节点的高可用集群 l  配置各节点互相解析 gb07 gb06 l  配置各节点时间同步 gb07 [root@gb07 ~]# ntp ...

随机推荐

  1. 迁移历史sql数据

    --select * into Trade2018 from Aozzo_ODS..Trade t1 --where t1.Created<'2019-01-01' --创建索引 --creat ...

  2. 论文阅读: VITAMIN-E: Extremely Dense Feature Points

    Abstract propose了一种非直接法叫"VITAMIN-E": 准确而鲁邦, 跟踪的是稠密特征. 传统非直接法对于重建稠密几何有难度因为他们对于点的选择(为了匹配)很慎重 ...

  3. 如何定时查询某线程的CPU执行时间

    #!/bin/bash pid=$(ps -T -p $(pgrep xxx) | grep xxx | gawk -F" " '{print $2}') if [ -z $pid ...

  4. Vue.js 源码分析(十三) 基础篇 组件 props属性详解

    父组件通过props属性向子组件传递数据,定义组件的时候可以定义一个props属性,值可以是一个字符串数组或一个对象. 例如: <!DOCTYPE html> <html lang= ...

  5. 如何在Quartus II中查看RTL原理图

    整个工程代码编写并且编译完成之后,标题栏选择Tools→Netlist Viewers→RTL Viewer即可

  6. Spring Boot 静态页面跳转

    本篇博客仅为自己提个醒:如何跳转页面而不麻烦控制器. 当我们创建 Spring Boot 项目时(勾选了 Thymeleaf 和 Web),目录结构会是如下:        其中图二是我创建了一个 h ...

  7. thinkphp3.2.3集成phpexcel1.8导出设置单元格合并

    1 到这里下载classes里面的文件 https://github.com/PHPOffice/PHPExcel 2 然后放到 thinkphp的vendor 新建一个文件夹 Phpexcel  然 ...

  8. C# 与 Java 的一些差异

    如果你是 Java 开发人员,则可以在 Xamarin 平台上充分利用你的技能和现有代码,同时获得 C# 的代码重用优势.你会发现 C# 语法与 Java 语法非常相似,这两种语言提供非常类似的功能. ...

  9. 用友U9 查看功能页面实体

    对着当前页面右键查看属性:   在链接后面加上&__dm=true    在打开的页面将鼠标放到字段上,可以看到页面实体是那一个.

  10. 自回归(auto-regression)机制

    在每个新单词产生后,该单词就被添加在之前生成的单词序列后面,这个序列会成为模型下一步的新输入.这种机制叫做自回归(auto-regression),同时也是令 RNN 模型效果拔群的重要思想. GPT ...