本文主要是介绍c# GC回收与代码块作用范围的问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近在学socket编程,于是自己学着写了一个通信程序。
自定义一个用于传递通信信息的类,通过Json实现序列化和反序列化达到传输这个类的目的。
以下是byte[]和Message类的互相转化代码
<span style="white-space:pre"> </span>public static byte[] serialize(MessageObject msg){DataContractJsonSerializer ds = new DataContractJsonSerializer(typeof(MessageObject));MemoryStream ms = new MemoryStream();ds.WriteObject(ms, msg);return ms.ToArray();}public static MessageObject deserialize(MemoryStream ms){DataContractJsonSerializer ds = new DataContractJsonSerializer(typeof(MessageObject));MessageObject msg = ds.ReadObject(ms) as MessageObject;return msg;}
但是在运行过程中出现了问题。
例:
第一次,传送消息"abc",成功
第二次,传送一张大图,成功
第三次,传送消息“abc",失败,异常:反序列化失败
经输出一些信息发现:若第一次传送byte[]长度为379(包含其他内容如传送时间,目的IP和端口等),第二次byte[]长度为1687535,则第三次传送byte[]长度远大于379
并且这种失败情况出现于文本长度为:短-长-短 的情况。
最后经调试成功解决,问题源于byte[]的定义在try catch的外部,而连接socket,接收byte[]等主要操作在try catch内部(每次接收byte[]都进行了new操作)
猜测原因: GC没有回收byte[]的内存(未出try catch代码块),尽管每次接收数据之前都进行new操作,但长byte的冗余数据还存在于内存中,导致新byte[]长度偏长,反序列化失败。
总结:考虑周全变量的生命周期,避免未进行回收的内存再次使用。
这篇关于c# GC回收与代码块作用范围的问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!