使用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()
修复了这个问题。但它显然减缓了一切。我该如何妥善处理?
答案 0 :(得分:1)
protobuf-net本身不会保留旧消息 - 事实上,如果 这样做,GC.Collect
就不会有帮助。
我能看到的第一件事是等待DataAvailable
的热循环真的昂贵;这可能会干扰GC
。我能看到的第二件事是你可以在睡觉之前在o
释放对象;作为一个随机的尝试,也许:
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
}
}