码迷,mamicode.com
首页 > Web开发 > 详细

.Net 使用sos.dll调式OutOfMemoryException

时间:2015-09-12 18:58:27      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:

做了几年的.net开发,还是第一次实际碰到抛出OutOfMemoryException的情况,做了一下代码检查,没有发现什么问题,就决定用sos.dll调试一下。

sos.dll是一个扩展库,用来帮助在visual studio或者windows debugger(WinDbg.exe)里面调试managed的程序,它可以提供CLR内部的情况。对于内存耗尽这种现象,很可能是因为有root还指向着对象而没有被垃圾回收,如果你从代码里面不能很容易找出是哪里,sos.dll应该能帮助解决这类问题。

使用Sos.dll也很简单,首先使用WinDbug.exe attach到要调试的程序上,然后load sos.dll,如下图:技术分享

我们这次碰到的OutOfMemoryException是很快出现的,考虑是由于大的对象造成里,我们程序里使用了一个16M的字节数组,使用命令 !DumpHeap -min 1000000列出堆里大于1百万个字节的对象, 输出如下图:

技术分享

 


从里面看到确实是有几个16M的对象,随便找一个对象使用命令GCRoot查看它的root,输出如下图:技术分享


从结果里看到这个对象确实还有root指着它,简单分析了一下,猜测可能跟使用SocketAsyncEventArgs对象有关系,Google了一下,发现其他人也碰到过类似的情况,由于使用SocketAsyncEventArgs不当造成内存泄漏。修改了一下程序,显式的调用了SocketAsyncEventArgs的Dispose,问题解决。

SocketAsyncEventArgs对象实现了IDispose模式,按道理来说,如果没有直接调用Dispose,会在Finalize的时候释放资源,但是SocketAsyncEventArgs对象比较特殊,必须显式的调用Dispose,否则就可能造成内存泄漏,这个对象里面封装了一个东西,会提交给IO完成端口,实现上比较特殊。

总结:

  1. 如果碰到奇怪的内存问题,从代码上没有看出来什么原因,可以考虑使用sos.dll进行调试。
  2. SocketAsyncEventArgs对象有可能造成内存泄漏。

.Net 使用sos.dll调式OutOfMemoryException

标签:

原文地址:http://www.cnblogs.com/hsdtt/p/4803403.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!