c# GC回收與程式碼塊作用範圍的問題
阿新 • • 發佈:2018-11-06
最近在學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[]長度偏長,反序列化失敗。
總結:考慮周全變數的生命週期,避免未進行回收的記憶體再次使用。