zoukankan      html  css  js  c++  java
  • Windbg找出managed对象memory leak的一种笨办法

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

    • 用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
    );



    更多阅读

    Capturing memory dumps for 32-bit processes on an x64 machine
    https://blogs.msdn.microsoft.com/tess/2010/09/29/capturing-memory-dumps-for-32-bit-processes-on-an-x64-machine/

    Correlating the output of !eeheap -gc and !address
    https://blogs.msdn.microsoft.com/maoni/2006/11/08/correlating-the-output-of-eeheap-gc-and-address/

    Debugging with the Right Tools
    https://blogs.msdn.microsoft.com/maoni/2010/04/23/debugging-with-the-right-tools/

  • 相关阅读:
    Oracle 推出 ODAC for Entity Framework 和 LINQ to Entities Beta版
    Entity Framework Feature CTP 5系列文章
    MonoDroid相关资源
    MSDN杂志上的Windows Phone相关文章
    微软学Android Market推出 Web Windows Phone Marketplace
    使用 Visual Studio Agent 2010 进行负载压力测试的安装指南
    MonoMac 1.0正式发布
    Shawn Wildermuth的《Architecting WP7 》系列文章
    使用.NET Mobile API即51Degrees.mobi检测UserAgent
    MongoDB 客户端 MongoVue
  • 原文地址:https://www.cnblogs.com/fbird/p/5889596.html
Copyright © 2011-2022 走看看