Windbg找出memory leak的一种笨办法

  以下内容是转自 http://www.cnblogs.com/fbird/p/5889596.html

  以前做项目碰到过一个问题,在客户的站点上面发现有严重的内存泄漏。幸运的是我们找到了重现的步骤,一轮下来大概有几十兆的泄漏,但是以下常规方法却没啥用。

  • 用windbg把heap上面的object全部dump下来,和上一轮操作作比较,并不能发现什么有用的东西。
  • 大对象heap上面也没啥有用的东西。
  • 像.net memory profiler这种比较智能的工具也用不上,因为一轮操作下来已经能使工具out of memory。

  项目有几百万行代码,但是我们认为可能发生大内存泄漏的就几个点。把那几个点的代码都找了一遍,没有任何结果。左寻右找,终于找到了一种比较笨但是却很管用的方法。

1. 打开Windbg, attach进程。

2. 加载symbol

3. 打断点 (可以用.logopen c:\memoryleak.txt把log记下来)

bp kernel32!virtualalloc ".printf\"#alloc memory# %lu  \\n \",dwo(esp+8);!clrstack;g;"

4. 输入g然后回车让进程继续跑。

5. 将重现步骤跑一遍,然后去review日志。

  接下来的过程比较笨,Review日志的过程中找到比较可疑的申请大块内存的点,注释代码,编译Assembly替换,看内存泄漏还在不在。最终还是找到了那个泄漏的地方,一个remoting的proxy,出了作用域但是其指向的内存去没有被自动释放。

解决这个问题的最关键的就是下面这条命令:
     bp kernel32!virtualalloc ".printf\"#alloc memory# %lu  \\n \",dwo(esp+8);!clrstack;g;"

  它的作用就是在kernel32的virtualalloc函数上面打断点,当该函数被执行到的时候,就把该函数申请的内存数量(在esp+8这个位置,dwo是把这个里面的值转成十进制),以及调用该函数的托管栈(clrstack)打印出来,然后让函数继续跑(g)。

  需要说明的是,这个命令仅对32位进程有效,因为根据32位cpu的calling convention,esp+4是第一个参数位置,esp+8是第二个,以此类推。64位的进程要去再查一下对应的calling convention看相关参数在哪个位置。

LPVOID WINAPI VirtualAlloc(
  _In_opt_ LPVOID lpAddress,
  _In_     SIZE_T dwSize,
  _In_     DWORD  flAllocationType,
  _In_     DWORD  flProtect
);
时间: 2024-10-10 14:31:28

Windbg找出memory leak的一种笨办法的相关文章

利用WinDbg找出程序崩溃的代码行号

http://blog.csdn.net/ccnyou/article/details/8879536 此文转载自VC驿站:http://www.cctry.com/forum.php?mod=viewthread&tid=41078 之前碰到论坛里有几个好友,说程序不时的崩溃,什么xxoo不能read的! 如果光要是这个内存地址,估计你会疯掉~~ 所以分享一下基本的调试技巧,需要准备的工具有WinDbg + VC6.0, 下面是自己整理的一份自动生成DUMP文件的源代码,只需要添加到工程即可,

TF-IDF与余弦相似性的应用(二):找出相似文章

上一次,我用TF-IDF算法自动提取关键词. 今天,我们再来研究另一个相关的问题.有些时候,除了找到关键词,我们还希望找到与原文章相似的其他文章.比如,"Google新闻"在主新闻下方,还提供多条相似的新闻. 为了找出相似的文章,需要用到"余弦相似性"(cosine similiarity).下面,我举一个例子来说明,什么是"余弦相似性". 为了简单起见,我们先从句子着手. 句子A:我喜欢看电视,不喜欢看电影. 句子B:我不喜欢看电视,也不喜欢看

9.11排序与查找(六)——给定M*N矩阵,每一行、每一列都按升序排列,找出某元素

/** * 功能:给定M*N矩阵,每一行.每一列都按升序排列,找出某元素. */ 两种方法: 方法一: /** * 思路:若列的末端大于x,那么x位于该列的左边:若行的开头小于x,那么x位于列的下边.从矩阵中的子矩阵中查找元素. * @param matrix * @param elem * @return */ public static boolean findElement(int[][] matrix,int elem){ int row=0; int col=matrix[0].len

用windbg+sos找出程序中谁占用内存过高,谁占用CPU过高(转载)

原文地址: http://www.cnblogs.com/Lawson/archive/2011/01/23/1942692.html 很早看到windbg+sos方面的知识,一直没仔细学习,也许因为自己做的系统还不够复杂,也没线上真实环境查看的权限,一直没学习这方面的知识,最近几天仔细找了这方面的资料,自己也写了个可能造成高CPU高内存的测试web页面,发现确实不错,即使一个生手,也可以用工具连蒙带骗的猜出哪里出了问题,当然对一些命令和内部标示更熟悉了后,可以更好的找出问题所在,非常值得学习.

在List中找出最大值的两种方法

先说需求:找出一个对象List中,某个属性值最大的对象. 1.定义对象 1 private class A 2 { 3 public int ID { get; set; } 4 5 public string Name { get; set; } 6 } 2.为两种方法定义两个时间段全局变量. 1 private static TimeSpan compare = new TimeSpan(); 2 private static TimeSpan order = new TimeSpan();

利用python找出两文件夹里相同的文件并保存在新的文件夹下(分三种情况)

原文件夹A,B,新文件夹C,下图中的情况以图片为例 A:00001.jpg  00002.jpg   00003.jpg  00147.jpg B : 00001.jpg  000000002.jpg   00147.json 第一种情况:找出两文件夹下相同内容的文件,保存并输出到文件夹C 思路:判断内容是否一致,因此需要读取整个文件,判断两者是否一样 由于文件内容错综复杂,而其md5是唯一的,如果两者内容一致,则两者的md5值应该为一样.由于图片是二进制存储,在读取时采用'rb'.这里是对文件

Tomcat出现To prevent a memory leak, the JDBC Driver has been forcibly unregistered.问题的一种情况记录

问题出现背景: 最近重构了一个老的项目,这个项目中间曾经参与维护的人比较多,代码非常乱,所以对其进行了一次小的重构和升级,将系统环境从JDK1.6+Tomcat6+WindowsServer升级JDK1.8+Tomcat8+Linux,但是重构完成的时候出现了错误,Tomcat一直无法启动. 错误信息 To prevent a memory leak, the JDBC Driver has been forcibly unregistered. 这个错误: 参考的资料 参考了stack ove

找出最大值和最小值的时间复杂度比较小的一种方法

       一般认为,对于给定的n个数,只要独立地找出最小值和最大值,各用n-1次比较,最多2(n-1)次就可以找出最大值和最小值.        实际上,至多3(n/2)次比较就足以同时找到最大值和最小值,具体做法是:成对的处理元素,先将一对元素互相比较,然后将最小者与当前最小值比较,将较大者与当前最大值比较,因此每两个元素需要3次比较.这里要注意n的奇偶,当n是奇数,就将最小值和最大值都设置为第一个元素,然后成对的处理剩下的元素:如果n是偶数,就对前两个元素做一次比较,以决定最大值和最小值

1.2 如何找出唯一成对的数(4种解法)

作者:acDream_ 来源:CSDN 原文:https://blog.csdn.net/acDream_/column/info/32487 原文是用Java实现的,自己理解后用C语言实现,记录下来. Problem:1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其他均只出现一次.设计一个算法,将它找出来,你能否设计一个算法实现? 思路1(最先想到的): 首先也是最暴力的方法就是一个循环嵌套一个循环,一个一个去找 时间复杂度为O(n²) 下面是实现的代码: