本文介绍了堆中保留的重叠数据未被删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的应用程序长时间(几个月或几年)保持一个开放的套接字连接,并保持不断连接并异步发送/接收数据。

Our application maintains an open socket connection for a long period of time (months or years) and stays constantly connected and sending/receiving data asynchronously.

我有记忆在堆中不断增加。 内存分析器将它追溯到异步套接字中的BeginSend。 在堆中它是OverlappedData,OverlappedCache和OverlappedAsyncResult。

I am having memory constantly increasing in the heap.  A memory analyzer traces it back to the BeginSend in the asynchronous socket.  In the heap it is OverlappedData, OverlappedCache, and OverlappedAsyncResult.

这个问题确实引起了头疼,我已经实现了一个池预先分配的缓冲区以消除内存泄漏。 这解决了BeginReceive / EndReceive端的问题。 它通过使用预先分配的缓冲池消除了BeginSend / EndSend
端的一些泄漏。

This issue has really caused a headache, and I've implemented a pool of pre-allocated buffers to get rid of the memory leak.  This fixed the issue for the BeginReceive/EndReceive side.  It got rid of some of the leaks for the BeginSend/EndSend side by using the pre-allocated buffer pool.

BeginSend代码如下所示:

The BeginSend code looks like this:

ConnectionBuffer connBuffer = new ConnectionBuffer();
$
connBuffer.ConnectionID = conn.ConnID;
$
connBuffer.PrimaryID = conn.RemotePrimaryID;

connBuffer.SecondaryID = conn.RemoteSecondaryID;
$
connBuffer.TertiaryID = conn.RemoteTertiaryID;
$
connBuffer.Buffer = BufferPool.GetBuffer(BufferIOType.Outbound);

if(connBuffer.Buffer!= null)

{

        Buffer.BlockCopy(data,0,connBuffer.Buffer.Data,0,data.Length);

        conn.Socket.BeginSend(connBuffer.Buffer.Data,0,data.Length,0,SendUnsecureMessageComplete,connBuffer);

}

ConnectionBuffer connBuffer = new ConnectionBuffer();
connBuffer.ConnectionID = conn.ConnID;
connBuffer.PrimaryID = conn.RemotePrimaryID;
connBuffer.SecondaryID = conn.RemoteSecondaryID;
connBuffer.TertiaryID = conn.RemoteTertiaryID;
connBuffer.Buffer = BufferPool.GetBuffer(BufferIOType.Outbound);
if (connBuffer.Buffer != null)
{
       Buffer.BlockCopy(data, 0, connBuffer.Buffer.Data, 0, data.Length);
       conn.Socket.BeginSend(connBuffer.Buffer.Data, 0, data.Length, 0, SendUnsecureMessageComplete, connBuffer);
}

这些ID用于识别邮件的发送对象。 对GetBuffer()的调用从缓冲池中获取预先分配的缓冲区。  BlockCopy正在将原始数据从先前的阵列复制到预先分配的内存空间。 
connBuffer对象是传递给回调函数SendUnsecureMessageComplete的状态对象。

Those IDs are for identifying who the message is sent to/from.  The call to GetBuffer() gets a pre-allocated buffer from the buffer pool.  The BlockCopy is copying the raw data from a previous array to the pre-allocated memory space.  The connBuffer object is the state object passed to the callback function SendUnsecureMessageComplete.

这是回调函数:

我是否可能需要使用GC.Collect()手动运行垃圾收集器回调函数? 我真的宁愿避免这种情况,但我不确定如何将这些OverlappedData对象从堆中取出来?

Is it possible that I need to manually run the garbage collector with GC.Collect() in the callback function?  I really would rather avoid that, but I'm not sure how to get those OverlappedData objects out of the heap?

感谢您的帮助你可以提供。

Thanks for any help you can provide.

推荐答案

感谢您在此发帖。

当我们实现回调函数时,我们应该确保垃圾回收器在回调函数完成其工作之前不回收委托。 

When we implement Callback Functions, we should ensure that the garbage collector does not reclaim the delegate before the callback function completes its work. 

我们做不建议在回调函数中使用GC.Collect()。

We do not suggest to use GC.Collect() in the callback function.

有关详细信息,请参阅MSDN文档。

For more details, please refer to the MSDN document.

https://docs.microsoft.com/en-us/dotnet/framework / interop / how-to-implement-callback-functions

最好的问候,

Wendy


这篇关于堆中保留的重叠数据未被删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 11:09