当前位置:首页 > 公众号精选 > CPP开发者
[导读]vmmap是sysinternals工具集中的一个工具,主要用于分析一个进程的虚拟内存和物理内存的使用情况。

vmmap是sysinternals工具集中的一个工具,主要用于分析一个进程的虚拟内存和物理内存的使用情况。更有效的是,可以通过对比两个不同时间的内存使用情况的Snapshot,来查找内存泄露问题。

vmmap介绍

当你用vmmap去查看一个正在运行的进程的时候。可以看到如下图,不同类型的内存使用采用不同的颜色标明。VMMap主要列举了以下几种类型的内存使用情况:
  • Free: 图中显示137434599232K,是不是被吓到了。这个一般是指虚拟地址空间。每个进程都有自己的虚拟地址空间,比如32位的一般为4G,其中2G是内核地址空间, 2GB用户态地址空间;64位理论上为2^64个字节,实际上没那么大,按照MSDN的描述64位的Windows用户态可使用地址空间为128TB。
  • Heap: 这个主要就是指我们通过C/C 的malloc, new;以及HeapAlloc等申请的内存大小
  • Image: 比较好理解,一般指进程启动的运行文件,比如Exe或者加载的DLL文件。
  • Managed Heap: 这个一般指用C#编写代码使用的托管堆。比如一个程序可能是C#和C 均有实现,这个时候可以查看是不是托管堆占用的内存持续增高,那么就可以判断一般是C#部分托管堆使用有问题造成了泄露。
  • Mapped File: 主要是指内存映射文件,熟悉的同学应该知道,这也是常用的进程间通信的一种方式。
  • Private Data: 主要指通过VirtualAlloc申请的内存空间。这里也注意同Free主要是指已经使用的地址空间,而非已经Commit的内存。比如下图中,
  • Stack: 函数栈所使用的内存大小
  • Shareable: 主要是进程间可以共享的内存,但是后备存储器为RAM或者Paging File(一般是指虚拟内存page.sys)。
  • Page Table: 主要指内核中和该进程页表相关联的内存

对于其他的描述,本人本人主要介绍两种需要关注的:
  • Committed: 对于一个虚拟地址空间的使用,我们可以是申请地址空间,但不提交(commit),如果不提交,则不会占用真实的存储器空间(比如RAM或者Paging File),只有commit后才会使用物理内存(RAM或者Paging File)。那么VMMap这里所指的内存就是后备存储器为RAM, Paging File, 或者Mapped file。
  • Working Set: 一般内存有RAM,还有虚拟内存(page.sys),而根据内存的调度原理,并不是所有的内存都常驻RAM。Working Set就是主要指在RAM中所使用的内存。

VMMap分析内存泄露

笔者曾经有一次用过VMMap分析过内存泄露,但是最终问题并不是通过VMMap分析出来的,主要是因为当运行到比较长的时间的时候VMMap偶尔会出现崩溃的情况。但是VMMap确实可以辅助分析出内存泄露问题,笔者也是将这个方法分享给大家。
下面是一段便于读者理解Vmmap分析方法的样例。首先每隔10秒钟,申请10M内存,总共申请10次;然后每隔10秒释放1次内存,只释放5次。这样操作,可以简单模拟,一个程序在运行中既有正常的内存申请释放的场景,也有申请后却没有释放的场景,这样交错在一起,让问题更加逼近现实。这样也便于使用这种方法,在未来碰到问题的时候进行实战。
#include
#include
#include
#include
void HeapMemoryLeakSample() {
const int iListSize = 10;
char* pHeapList[iListSize];
//Alloc 10 Heap STR_SIZE
const int STR_SIZE = 10 * 1000 * 1000;
for (int i = 0; i < iListSize; i ) {
pHeapList[i] = new char [STR_SIZE];
strcpy_s(pHeapList[i], STR_SIZE, "Alloc Memory");
std::cout << pHeapList[i] << std::endl;
std::this_thread::sleep_for (std::chrono::seconds(10));
}
//Free 5 Heap space
for (int i = 0; i < iListSize; i ) {
if (i % 2 == 0) {
delete pHeapList[i];
std::cout << "Free Memory" << std::endl;
std::this_thread::sleep_for (std::chrono::seconds(10));
}
}
}
int main() {
HeapMemoryLeakSample();
while (true) {
std::this_thread::sleep_for (std::chrono::seconds(10));
}
return 0;
}
接下来一起来查看是如何定位一个程序的内存泄露的。
第一步配置好程序的位置,工作目录,以及符号文件目录:


第二步当运行程序,首先看到整个VMMap界面。这个时候映入眼帘的好多好多数据,该看什么呢?首先对于一般的C 程序而言,堆的内存泄露使用是最常见,那么就先看下Heap部分的Committed大小是不是很大。比如本文的样例,发现已经有70M左右的大小。先锁定到溢出内存类型为Heap。

第三步个人认为查找内存泄露也需要一些技巧和常识的。比如程序刚启动不久的时候,申请的很多资源是全局的,或者伴随着整个进程的生命周期的,那么刚启动后的内存的增长一般可以忽略,不认为是内存泄露的原因。再大概程序运行一段时间后(根据自己程序实际情况而定),基本的伴随整个进程的生命周期的资源已经创建完毕。此时可以使用Timeline和Address部分的功能对照查看。
这个时候首先选择Heap(点击一下),那么Address部分将会显示Heap所占用的内存。然后当我们打开Timeline,选择特定的时间段区域,比如上图中选择区域为刚开始申请内存的部分,每隔10秒,增加申请10M内存。此时重要的是Address部分也会动态的展示这段时间的内存变化。

然后注意其中的内存使用比如000001B39E445000的内存被申请了,然后拉长时间线,发现很长时间还是存在在Address栏中,并且绿色,就说明一直没有被释放。

此时当你选中这个地址,再选择Heap Allocations,便可以看到其申请的大小为10000000, 双击打开后便可以查看到函数调用栈了。如下图所示便可以找到是在HeapMemoryLeakSample函数内调用了new,并且有行号提示(不过这里的行号提示不够精准,但是也不影响你去分析问题了)。
也可以不选择区间,而选个某个时间点,查看内存的状态。

第四步如果很幸运,第三步已经找到问题了。第四步本来想说一说Call Stack的追踪的,比如通过申请的内存的Count或者Bytes来查找到可疑的内存泄露点的函数调用栈。可是笔者多次实验后均发现,数据对不上。比如下图的Count百分比和Bytes百分比之和均对不上100%。所以笔者也不会对此做过多的赘述,调试软件同样也是软件,也可能存在bug或者一些限制。但是通过如上的方法和思想,也许能够协助你找到内存泄露点,至少可以起到辅助的作用。



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动模块RSC6218A 5W-18W迷你高效驱动电源应用,小功率、小体积、高效率

关键字: LED驱动模块 驱动电源应用 LED电源芯片

业内消息,近日台积电在北美技术研讨会上宣布,正在研发 CoWoS 封装技术的下个版本,可以让系统级封装(SiP)尺寸增大两倍以上,实现 120x120mm 的超大封装,功耗可以达到千瓦级别。

关键字: CoWoS 台积电 封装

据外媒报道,字节正在内部探索出售TikTok美国业务多数股权,并援引内部人士披露的信息称 “沃尔玛或为最理想买家”。报道还称,讨论中的一种情况是字节出售美国50%以上TikTok股份,但保留少数股权。

关键字: 字节跳动 TikTok

业内消息,HMD 正在计划重启一些经典的诺基亚功能手机。今年 3 月初,该公司预告了将于 5 月发布的一款功能手机。现在该机的身份已经曝光,新款诺基亚 3210 的谍照已经泄露,展现了新机部分新特性。

关键字: 诺基亚 功能机 HMD

业内消息,近日有一位网友在各大社交媒体发文表示,自己离职后,公司将自己所有的期权全部作废。

关键字: 期权 微博

业内消息,在昨天的中关村论坛未来人工智能先锋论坛上,生数科技联合清华大学正式发布中国首个长时长、高一致性、高动态性视频大模型——Vidu。Vidu是自Sora发布之后全球率先取得重大突破的视频大模型,性能全面对标Sora...

关键字: Sora 清华 AI Vidu

业内消息,近日高通公司宣布推出针对桌面平台的全新骁龙 X Plus 处理器。

关键字: 高通 骁龙 X Plus 处理器

近日,台积电在圣克拉拉年度技术研讨会上宣布首个“埃级”制程技术:A16。A16 是台积电首次引入背面电源输送网络技术,计划于 2026 年下半年开始量产。同时,台积电也在重新命名工艺节点,标志着「埃级」时代的开始。

关键字: 台积电 A16

4 月 25 日消息,4 月 25 日,国际数据公司(IDC)发布 2024 年第一季度中国手机市场跟踪报告,荣耀以 17.1% 的市场份额拿下第一,华为占 17.0% 位列第二,OPPO、苹果和 vivo 分别位列第三...

关键字: 荣耀 华为

业内消息, 近日华为全新Pura 70系列手机正式开售引发广大 数码爱好者追捧,但是有网友注意到这款手机的“AI修图”功能,竟然可以将照片中的人物衣服消除,并拍成视频发布网络。

关键字: 华为Pura70 华为
关闭
关闭