巴别塔上的雇工


Battle Against Memory Leak
11月 16, 2006, 2:12 下午
Filed under: 技术体会
这两天fix了一个关于memory leak的bug,中间颇多曲折,走了不少弯路,这里就长话短说,只说有用的。

一开始这个ASP.NET Web Service总是会神奇的crash,而且很难复现这个问题,最后在压力测试的时候就频繁出现,而且从Performance Counter里面可以看见运行这个web service的w3wp进程内存在频繁请求下一直增长,这样基本可以断定是有Memory Leak了。

首先需要知道哪里溢出了,这个Web Service是.Net代码,有垃圾回收机制撑腰,按道理不大可能出现内存问题,但是这个Service会利用.Net的Interop机制调用Native Code,Native Code分配的内存GC是控制不了的,所以自然怀疑是Native Code有问题。为了证实这一点,用Windows的Performance Counter监视压力测试下的IIS w3wp进程,关心的Counter有:private bytes, virtual bytes 和.NET CLR Memory bytes in All Heap,可以看到privates bytes和virtual bytes一直增长,而CLR控制的bytes in All Heap有升有降稳定在一定范围内,这就可以断定肯定是Native Code存在内存泄漏。

现在把注意力集中到Native Code上,在Unix环境下,可以用一个叫Valgrind的Free软件轻松发现Memory Leak,但是在Windows环境下比较像样的内存溢出检察软件都要收钱的,还好MSVCRT的Debug版自带了内存检测的机制,虽然不是图形化那样易用,但是也相当有效果。

要做的就是使用Debug版的MSVCRT,Build时加上_DEBUG的宏定义,这样,CRT的malloc/realloc/calloc/free函数行为会有所变化,调用malloc实际调用的时_malloc_dbg,这个函数会在分配的内存块中放置一些debug用得上得信息。对code稍做修改,在native code得入口用_CrtMemCheckpoint做一个记号,在出口用_CrtMemDumpAllObjectsSince看看这期间新分配了哪些内存块,可以看到这些内存块的信息(这篇文章详细介绍了Debug Heap),由此可以推导出内存泄漏的情况。


发表评论 so far
留下评论



留下评论