C#之异步导致内存泄漏

C#4.5的新特性,异步处理,同步的编码方式,大大的提高了编程效率。但是今天却由于异步的使用,导致了一个非常严重的内存泄漏。

崩溃截图:

由于本程序是用纯C#开发,不存在非托管内存,而且没有使用静态变量,为什么还是会有内存泄漏了。迷茫了一个上午。

快到中午的时候,一个偶然的机会,执行了异常清理,就是把异步等待进行超时处理之后,内存立马降下来了。

很快定位原因出在await一直没有得到应答上面。

通过研究发现,在调用await之后,系统会把await之前的函数变量都保存起来,等待应答到来之后,在恢复过来,然后好接下来处理。问题就出来这些函数变量上面。我有一个类需要保存起来,在应答回来之后使用。

                var MediaRsp = await ryMedia.GetTcpAcceptAsync(sdp_Request.parameters.sessionId).ConfigureAwait(false);
                if(MediaRsp.Result == RyResult.Success)
                {
                    RailwaySend railwaySend = new RailwaySend()
                    {
                        Media = MediaRsp.media,
                        SendType = SendType.RailWay,
                    };
                    session.AddSend(sdp_Request.parameters.sessionId, railwaySend);
                }

session类在另外一个线程一直在执行发送视频流的操作。

public void SendMedia(byte[] buffer)
{
      byte[] bSend = new byte[buffer.Length];
      Array.Copy(buffer, bSend, buffer.Length);
}

理论上讲,new的数据,是托管内存,应该会被Gcc回收,但是实际上没有。

结论:

await之前的涉及到的类,在await到达之前,所产生的托管内存都不会被Gcc回收。这就是导致最终内存泄漏的原因。

猜你喜欢

转载自blog.csdn.net/g0415shenw/article/details/81114862