.Net 使用sos.dll调式OutOfMemoryException

做了几年的.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对象有可能造成内存泄漏。

转载于:https://www.cnblogs.com/hsdtt/p/4803403.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值