1. 程式人生 > >c# GC回收與程式碼塊作用範圍的問題

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[]長度偏長,反序列化失敗。

總結:考慮周全變數的生命週期,避免未進行回收的記憶體再次使用。