3

在下面的代码中,似乎 client.Connect.Receive 永久固定“byte []结果”,导致内存永远不会被释放(因为它总是固定的)。我正在寻找一种方法来告诉 C# 结果在 this.OnReceive 中使用后不再需要固定,但我找不到执行此操作的内置函数或关键字。

有谁知道我如何让 C# 取消固定 byte[] 数组?(这是我的 C# 应用程序中内存泄漏的来源之一)

this.m_TcpListener = new TcpListener(this.p_TcpEndPoint.Port);
this.m_TcpThread = new Thread(delegate()
{
    try
    {
        this.m_TcpListener.Start();
        while (this.p_Running)
        {
            TcpClient client = this.m_TcpListener.AcceptTcpClient();
            new Thread(() =>
                {
                    try
                    {
                        // Read the length header.
                        byte[] lenbytes = new byte[4];
                        int lbytesread = client.Client.Receive(lenbytes, 0, 4, SocketFlags.None);
                        if (lbytesread != 4) return; // drop this packet :(
                        int length = System.BitConverter.ToInt32(lenbytes, 0);
                        int r = 0;

                        // Read the actual data.
                        byte[] result = new byte[length];
                        while (r < length)
                        {
                            int bytes = client.Client.Receive(result, r, length - r, SocketFlags.None);
                            r += bytes;
                        }

                        Console.WriteLine("Received TCP packet from " + (client.Client.RemoteEndPoint as IPEndPoint).Address.ToString() + ".");
                        this.OnReceive(client.Client.RemoteEndPoint as IPEndPoint, result, length);
                    }
                    catch (SocketException)
                    {
                        // Do nothing.
                    }

                    client.Close();                                
                }).Start();
            //this.Log(LogType.DEBUG, "Received a message from " + from.ToString());
        }
    }
    catch (Exception e)
    {
        if (e is ThreadAbortException)
            return;
        Console.WriteLine(e.ToString());
        throw e;
    }
}
);
this.m_TcpThread.IsBackground = true;
this.m_TcpThread.Start();
4

1 回答 1

5

您可以自己固定/取消固定它,因此:

//Pin it 
GCHandle myArrayHandle = GCHandle.Alloc(result,GCHandleType.Pinned);
//use array
while (r < length)
{
    int bytes = client.Client.Receive(result, r, length - r, SocketFlags.None);
    r += bytes;
}
//Unpin it
myArrayHandle.Free();

但我个人对 client.Connect.Receive 将其“永远”固定感到非常惊讶。我以前用过它(我相信很多人都用过)并且没有遇到这种类型的问题。或者,如果您确定这是问题所在,那么您可以在整个 while 循环中重复使用一个结果数组,而不是每次都分配一个新的结果数组(在启动侦听器的位置分配它,并且每次只使用 lenbytes 字节)。

于 2011-01-28T16:38:57.960 回答