当前位置:首页 > 公众号精选 > CPP开发者
[导读]vmmap是sysinternals工具集中的一个工具,主要用于分析一个进程的虚拟内存和物理内存的使用情况。更有效的是,可以通过对比两个不同时间的内存使用情况的Snapshot,来查找内存泄露问题。vmmap介绍当你用vmmap去查看一个正在运行的进程的时候。可以看到如下图,不同...

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

vmmap介绍

当你用vmmap去查看一个正在运行的进程的时候。可以看到如下图,不同类型的内存使用采用不同的颜色标明。VMMap主要列举了以下几种类型的内存使用情况:

  • Free: 图中显示137434599232K,是不是被吓到了。这个一般是指虚拟地址空间。每个进程都有自己的虚拟地址空间,比如32位的一般为4G,其中2G是内核地址空间, 2GB用户态地址空间;64位理论上为2^64个字节,实际上没那么大,按照MSDN的描述64位的Windows用户态可使用地址空间为128TB

  • Heap: 这个主要就是指我们通过C/C 的mallocnew;以及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

第三步 个人认为查找内存泄露也需要一些技巧和常识的。比如程序刚启动不久的时候,申请的很多资源是全局的,或者伴随着整个进程的生命周期的,那么刚启动后的内存的增长一般可以忽略,不认为是内存泄露的原因。再大概程序运行一段时间后(根据自己程序实际情况而定),基本的伴随整个进程的生命周期的资源已经创建完毕。此时可以使用TimelineAddress部分的功能对照查看。

这个时候首先选择Heap(点击一下),那么Address部分将会显示Heap所占用的内存。然后当我们打开Timeline,选择特定的时间段区域,比如上图中选择区域为刚开始申请内存的部分,每隔10秒,增加申请10M内存。此时重要的是Address部分也会动态的展示这段时间的内存变化。

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

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

也可以不选择区间,而选个某个时间点,查看内存的状态。

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

- EOF -

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

据韩联社报道,上周三星电子发布业绩报告显示,随着芯片价格反弹,预计今年第一季度营业利润同比骤增931.25%,为6.6万亿韩元(当前约合人民币354.6亿元),已经超过了2023年全年营业利润6.57万亿韩元。

关键字: 内存 三星

TDK 株式会社(TSE:6762)进一步扩充 Micronas 嵌入式电机控制器系列 HVC 5x,完全集成电机控制器与 HVC-5222D 和 HVC-5422D,以驱动小型有刷(BDC)、无刷(BLDC)或步进电机...

关键字: 嵌入式 电机控制器 内存

Apr. 04, 2024 ---- TrendForce集邦咨询针对403震后各半导体厂动态更新,由于本次地震大多晶圆代工厂都位属在震度四级的区域,加上台湾地区的半导体工厂多以高规格兴建,内部的减震措施都是世界顶尖水平...

关键字: 晶圆代工 内存

美光坚持多元、平等、包容的企业文化,携手社区推行公益

关键字: 内存 存储 美光

今天,小编将在这篇文章中为大家带来虚拟内存的有关报道,通过阅读这篇文章,大家可以对虚拟内存具备清晰的认识,主要内容如下。

关键字: 内存 虚拟内存

在这篇文章中,小编将对虚拟内存的相关内容和情况加以介绍以帮助大家增进对它的了解程度,和小编一起来阅读以下内容吧。

关键字: 内存 虚拟内存

以下内容中,小编将对物理内存的相关内容进行着重介绍和阐述,希望本文能帮您增进对物理内存的了解,和小编一起来看看吧。

关键字: 内存 物理内存

美光 LPDDR5X 和 UFS 4.0 以高带宽、高能效以及大容量助力荣耀人工智能创新

关键字: AI 内存 存储 智能手机

第五代英特尔至强铂金 8592+处理器凭借更优化的SoC,三倍更大缓存和更快内存,在运行诸多工作负载时具备与众不同的优势,尤其是AI工作负载。

关键字: 至强处理器 SoC 内存

LPCAMM2内存模块以更高性能、更低功耗、更小的外形规格助力笔记本电脑实现更快速度、更小巧尺寸和更强续航,并通过模块化设计为升级和维修提供便利

关键字: 笔记本电脑 内存 AI
关闭
关闭