最近项目突然收到了一个紧急的问题报告 - 用户在进行某些关键操作的时候整个软件突然就crash掉了。幸好产品继承了自动抓取dump的功能。。。

 
收到dump之后,通过windbg打开,查看相应的callstack。迅速定位到出错的线程。在调用MapViewOfFile()的时候没有map成功导致crash。
 
接下来,我们需要知道为什么为何map失败?通过GetLastErrorCode(),我们得知进程OutOfMemory导致map失败。MapViewOfFile()需要映射512KB(4Mb)连续内存,而通过!address -summary命令,我们发现系统里最大的连续内存块为1.5Mb。Crash因此发生了。
 
 
至此,我们可以肯定,该crash是由于memory leak造成MapViewOfFile()失败。那么,是什么leak了?重新看上面的输出信息,我们可以看到,MEM_MAPPED使用的内存高达934Mb,MEM_PRIVATE使用的内存为805Mb。据此,我们怀疑,产品里所使用的memory mapped file可能会存在大量的leak。
 
运行命令!address -f:MEM_MAPPED,会得到类似的输出:
 
第三列,也就是RgnSize,为当前MMF的映射窗口大小。查看了该输出,我们发现,窗口大小为512kB的文件在500个左右,而大小为256KB的文件多大1800个。据此,我们可以锁定这些256KB的MMF文件。
 
下面的问题,就是,谁映射了这么多的MMF文件?在此不同的项目可以有不同的方法。如果你很熟悉项目数据的话,你可以先通过dd查看一下该256KB的内容都是啥?有没有你所熟悉的内容?如果是字符串的话那就更容易定位问题的所在地方了。
 
这里,我们假设我们不熟悉文件的内容,从而无法猜测这些数据是谁产生的。我们只能采取其他办法。
 
上面输出的第一列,也就是BaseAddr,为该map view的地址。如果我们要使用该map view的话,我们必须要有对应的指针指向该view。因此,我们随机选了一个256KB的view的baseaddress,然后通过下面的命令查找谁还指向了这块内存。
 
 
从该输出我们能够看到,大概有10多个地方保存有该指针地址。接下来,我们就需要查看谁,也就是那些类的instance还保存这些地址。此处没有其他好的办法,只能在这些地址四处通过dds命令来查看是否有对象的symbol。
 
在查看了多个地址之后,我们发现,有一个vftable为CMMFSerializer的对象。这给了我们极大的肯定:该类名里有MMF!十有八九是该类的leak!
 
接下来,我们的目标为谁创建了CMMFSerializer对象而没有销毁?首先,我们通过x命令来获得CMMFSerializer的虚表地址,这样我们就能够在heap里搜索这些对象都存在哪里。
 
然后,运行!heap命令,就能够查看到拥有这些对象的地址了。
从我们的输出能够看到,大量的CommunicatorObj对象存在heap里。这就说明了CommunicatorObj这些对象没有被删除掉。从而,我们可以做这样的结论:CommunicatorObj的泄漏导致了如此之多的MMF的泄漏,以及很高的MMF_PRIVATE使用率如此之高。剩下来的工作就很简单了,看看代码,分析分析哪些地方使用了CommunicatorObj。
 
 

MemoryMappingFile泄漏分析过程的更多相关文章

  1. 一个驱动导致的内存泄漏问题的分析过程(meminfo->pmap->slabtop->alloc_calls)

    关键词:sqllite.meminfo.slabinfo.alloc_calls.nand.SUnreclaim等等. 下面记录一个由于驱动导致的内存泄漏问题分析过程. 首先介绍问题背景,在一款嵌入式 ...

  2. Erlang 内存泄漏分析

    随着项目越来越依赖Erlang,碰到的问题也随之增加.前段时间线上系统碰到内存高消耗问题,记录一下troubleshooting的分析过程.线上系统用的是Erlang R16B02版本. 问题描述 有 ...

  3. Java内存泄漏分析与解决方案

    Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最快最好的检测程序的稳定性,防止系统崩盘,作者用自已的亲身经历 ...

  4. Android内存泄漏分析及调试

    尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/13017999 此文承接我的另一篇文章:Android进程的内存管理分析 首先 ...

  5. Android 内存泄漏分析与解决方法

    在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...

  6. Java内存泄漏分析系列之六:JVM Heap Dump(堆转储文件)的生成和MAT的使用

    原文地址:http://www.javatang.com JVM Heap Dump(堆转储文件)的生成 正如Thread Dump文件记录了当时JVM中线程运行的情况一样,Heap Dump记录了J ...

  7. Java内存泄漏分析系列之五:常见的Thread Dump日志案例分析

    原文地址:http://www.javatang.com 症状及解决方案 下面列出几种常见的症状即对应的解决方案: CPU占用率很高,响应很慢 按照<Java内存泄漏分析系列之一:使用jstac ...

  8. Java内存泄漏分析系列之二:jstack生成的Thread Dump日志结构解析

    原文地址:http://www.javatang.com 一个典型的thread dump文件主要由一下几个部分组成: 上图将JVM上的线程堆栈信息和线程信息做了详细的拆解. 第一部分:Full th ...

  9. Java内存泄漏分析系列之一:使用jstack定位线程堆栈信息

    原文地址:http://www.javatang.com 前一段时间上线的系统升级之后,出现了严重的高CPU的问题,于是开始了一系列的优化处理之中,现在将这个过程做成一个系列的文章. 基本概念 在对J ...

随机推荐

  1. YTU 2610: A改错题--体检情况分析

    2610: A改错题--体检情况分析 时间限制: 1 Sec  内存限制: 128 MB 提交: 233  解决: 161 题目描述 注:本题只需要提交标记为修改部分之间的代码,请按照C++方式提交. ...

  2. Java生成可执行文件 & MANIFEST.MF问题 METAINFO

    用 Intellij 进行打包.在File -> Project Structure里面. 然后应该会自动生成Jar包(也可以Build->Build Artifacts) xxx.jar ...

  3. DataGridView 相关操作

    一.单元格内容的操作// 取得当前单元格内容 Console.WriteLine(DataGridView1.CurrentCell.Value); // 取得当前单元格的列 Index Consol ...

  4. js方式进行地理位置的定位api搜集

    新浪 //int.dpool.sina.com.cn/iplookup/iplookup.php?format=js //int.dpool.sina.com.cn/iplookup/iplookup ...

  5. 记一次高级java工程师职位的面试

    阿里在业内做java方面的有关开发可谓是一流的.它给我的第一印象,就是办事效率很高. 周日简历发过去,周一电话就打过来了,接到电话后,面试官很客气,问现在方面吗,我说现在在上班,有点忙,然后和面试官约 ...

  6. Android activity 周期图

  7. UVa 1595 (水题) Symmetry

    颓废的一个下午,一直在切水题,(ˉ▽ ̄-) 首先如果这些点是对称的话,那么它们的对称轴就是x = m,m是横坐标的平均值. 把这些点放到一个集合里,然后扫描每个点,计算出它关于x = m的对称点,看这 ...

  8. BZOJ 2120/BZOJ 2453

    分块傻逼题. memset很慢的...而且其实也没有用.... #include<iostream> #include<cstdio> #include<cstring& ...

  9. MIPI DSI 和 D-PHY 初始化序列

    MIPI DSI 和 D-PHY 初始化序列 -- 深圳 南山平山村 曾剑锋 参考文档: i.MX 6Dual/6Quad Multimedia Applications Processor Refe ...

  10. Intent七大属性

    一.Intent的作用是什么?    1.Intent 用于封装程序的”调用意图“.两个Activity之间,可以把需要交换的数据封装成Bundle对象,然后使用Intent携带Bundle对象,实现 ...