程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#中考慮為大對象使用弱引用,

C#中考慮為大對象使用弱引用,

編輯:C#入門知識

C#中考慮為大對象使用弱引用,


  1.無論怎樣盡力,我們總是會使用到某些需要大量內存的數據,而這些內存並不需要經常訪問。或許你需要從一個大文件中查找某個特定的值,或者算法需要一個較大的查詢表。這時,你也許會采用2中不太好做法:第一種是創建一個本地變量,然後在每次執行該算法時都生成一大塊垃圾;第二種則是創建一個成員變量,在很長一段時間內都占用著這一大塊內存。很多時候這兩種做法都不是非常好。

  2.有沒有一種好的選擇來處這個問題呢?答案是創建弱引用,弱引用的對象和垃圾對象差不多,程序會告訴垃圾收集器該對象可以被回收,不過在回收之前你仍舊有一個引用,可以用來在需要的時候訪問到該對象。若能合理使用該策略,弱引用將和垃圾收集器協同工作,從而優化內存使用。如下代碼說明:

    /// <summary>
    /// 大對象類型
    /// </summary>
    public class MyLargeClass
    {
        private int[,] matrix;
        private ushort matrixXDimension;
        private ushort matrixYDimension;
        public string reallyLongMessage;

        private static WeakReference _weakObj;
        public static object WeakObj
        {
            get
            {
                return _weakObj?.Target;//“?.”語法為C#6.0的新特性,對應.Net Framework 4.6。表示若為空則返回空,若不為空則獲取其相應的屬性值
            }
            set
            {
                _weakObj = new WeakReference(value);//弱引用的創建
            }
        }

        public MyLargeClass(ushort matrixXDimension, ushort matrixYDimension)
        {
            this.matrixXDimension = matrixXDimension;
            this.matrixYDimension = matrixYDimension;
            matrix = new int[matrixXDimension, matrixYDimension];
        }

        private void Initialize()
        {
            //TODO 做更多的數據初始化
            //對matrix二維數組的數據加載
        }

        public long Calculate()
        {
            //TODO 處理對matrix對象計算結果
            return matrixXDimension * matrixYDimension * 1000;
        }

        public static void Execute()
        {
            //從弱引用中獲得大對象,若沒有弱引用或弱引用已被回收,此時就需要重新創建對象。
            MyLargeClass myLargeObject = WeakObj as MyLargeClass;//myLargeObject可為本地變量,也可為成員變量
            if (myLargeObject == null)
            {
                myLargeObject = new MyLargeClass(1000, 1000);
            }
            //TODO 對myLargeObject對象中的數據進行處理

            //處理完成後,把大對象歸到弱引用,然後把myLargeObject設置為null,表明大對象無引用。此時,系統會認為myLargeObject所指向的對象可以被垃圾收集。若垃圾收集器在此時運行,那麼將會回收該對象。不過若是在回收之前,你再次需要該對象,只需如上面的4行代碼處理即可。
            WeakObj = myLargeObject;
            myLargeObject = null;
        }
}

  3.從上面的Execute()方法的2處代碼中,可以看出對象的使用與清理交給了運行時處理,這是簡單的使用場景,不過很多時候現實並不是那麼簡單,很少有對象會完全與外界隔離。任何一個大對象都包含了對其他對象的引用。若一個大對象被標記為弱引用,則其內部引用對象也將被標記為弱引用。被標記的弱引用對象就會被回收(不是馬上回收)。

  4.對於實現了IDisposable的對象,則不應該使用弱引用,因為被釋放的對象已經不能再弱引用,且在弱引用中你也不能調用Dispose()。所以弱引用應該配合非IDisposable的大對象使用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved