1

使用 TCPClient 的 NetworkStream 和 protobuf-net 我通过 TCP 发送和接收 protobuf 消息。接收是通过在自己的线程中运行的以下方法完成的:

private void HandleClientComm()
{
    using (NetworkStream stream = m_Stream)
    {
        object o;
        while (true)
        {
            if (stream.CanRead && stream.DataAvailable)
            {
                o = null;
                if (Serializer.NonGeneric.TryDeserializeWithLengthPrefix(stream, PrefixStyle.Base128, Utilities.CommunicationHelper.resolver, out o))
                {
                    if (o != null)
                    {
                        //Do something with the incoming protobuf object
                    }
                }
                Thread.Sleep(1);
            }
        }
    }   
}

这工作正常,但我有垃圾收集的问题。似乎旧的 protobuf 对象仍保留在内存中。一段时间后,大消息会导致 System.OutOfMemoryExceptions。

GC.Collect()在睡觉前显式调用可以解决这个问题。但它显然减慢了一切。我该如何正确处理?

4

1 回答 1

1

protobuf-net 本身不会保留旧消息 - 事实上,如果它这样做,那GC.Collect将无济于事。

我首先看到的是等待的热循环非常DataAvailable昂贵;这可能会干扰. 我可以看到的第二件事是,您可能可以在睡觉前释放对象;作为一个随机的尝试,也许:GCo

using (NetworkStream stream = m_Stream)
{
    object o;
    while (Serializer.NonGeneric.TryDeserializeWithLengthPrefix(
        stream, PrefixStyle.Base128,
        Utilities.CommunicationHelper.resolver, out o))
    {
        if (o != null)
        {
            //TODO: Do something with the incoming protobuf object

            // clear o, just to give GC the very best chance while we sleep
            o = null;
        }
        Thread.Sleep(1); // <=== not sure why you want to sleep here, btw
    }
}
于 2013-06-06T08:50:28.767 回答