中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

基(ji)礎才是重中(zhong)之(zhi)重~對(dui)象的(de)生與死

回到目錄

為何要寫

之所以寫這篇文章,完全是因為學生們(men)(men)在實際開發中遇到(dao)的(de)問(wen)題(ti),一個對(dui)(dui)象(xiang)占用(yong)的(de)內存空間總不(bu)被釋放(fang),導(dao)致系(xi)(xi)統內存不(bu)斷攀(pan)升,其最主要(yao)原因是我們(men)(men)對(dui)(dui)“對(dui)(dui)象(xiang)的(de)生與死”不(bu)清楚,或者從來沒有(you)認真去考慮(lv)過這件事,確(que)(que)實一個對(dui)(dui)象(xiang)在被聲音,初始化,使(shi)用(yong)或者最后(hou)被系(xi)(xi)統回收(shou)(shou),整個的(de)過程與我們(men)(men)關系(xi)(xi)確(que)(que)實不(bu)大,我們(men)(men)開發人員(yuan)直接用(yong)就(jiu)行了,對(dui)(dui)于C#這種托(tuo)管語(yu)言你沒必(bi)要(yao)去自己回收(shou)(shou)它(ta),但有(you)時,我們(men)(men)多了解一點系(xi)(xi)統的(de)回收(shou)(shou)機制,對(dui)(dui)我們(men)(men)的(de)程序還(huan)是很有(you)好處的(de)。

對象的種類(根據作用域)

1 類對象,靜態對象,使用static修飾符進行聲明,作用域為整個類(所有實體公有),當(dang)你(ni)(ni)的程序運行期間它(ta)一直(zhi)不(bu)(bu)會被回收(shou),直(zhi)到你(ni)(ni)的進程結(jie)束(shu)(所(suo)以使用(yong)它(ta)要注冊,大數據一般不(bu)(bu)用(yong)類對象存儲)

2 類級別的實例對象,它定義在類里,方法體外面,作用域為整個類的當前實例,它(ta)的回(hui)收(shou)時機我們無(wu)法確定(ding),當然(ran)你可以手動(dong)進行  GC.Collect()來馬上(shang)釋(shi)放它(ta),否則由系統的垃圾回(hui)收(shou)機制(zhi)管理它(ta)

3 方法級別的實例對象,局部對象,它定義在方法內部,作用域為當前方法體,方法執行完成(cheng)后,自動釋放(fang)

代碼中(zhong)的實驗

    public class Product
    {
        ~Product()
        {
            Logger.LoggerFactory.Instance.Logger_Info("Product對象已經被釋放");
        }
        public int ID { get; set; }
        public string Name { get; set; }
    }

    public class ProductConfig
    {
        ~ProductConfig()
        {
            Logger.LoggerFactory.Instance.Logger_Info("ProductConfig對象已經被釋放");
        }
        public int ID { get; set; }
        public string Name { get; set; }
    }
        /// <summary>
        /// 類級別的(de)
        /// </summary>
        ProductConfig productConfig = new ProductConfig();
        public ActionResult Create()
        {
            /// <summary>
            /// 實例成員,方法(fa)體里(li)
            /// </summary>
            Product product = new Product();
            GC.Collect();//清除全局(ju)實例(li)成員(yuan),否則全局(ju)實例(li)對象將不(bu)會馬上(shang)清楚,它會等待垃圾回收
            return View();
        }

上面代碼在執行后,會寫入日志文件,由于在方法里使用了GC.Collect()方法,這時全局實例對象ProductConfig將會在方法執行后被釋放,如果不加這個方法,那么ProductConfig何(he)時釋(shi)放,我們(men)是(shi)不知道的(de)。

Dispose模式

對上面的操作是我們刻意去進行的,意思就是讓大家看到,對象何時會被釋放,而對象在被釋放后,會執行類的析構方法(~開頭的),它在C#里很少被使用,或者我們很少關注它,因為你不去實現它,系統垃圾回收結束后也會去調用它,這是對于托管資源說的,我們在C#這個開發語言里,有時也會涉及到使用一些“非托管”資源,比如數據庫連接,網絡通訊,文件訪問等等,它們是不受當前Frameworks CLR控制的,或者說CLR也控制不了它,因為它已經脫離了當前應用程序,這也算是合情合理,這時,這些非托管資源會實現自己的“資源釋放”方法,好Dispose,大家如果有心的話,都會發現像文件,SQL連接,socket,Tcp等對象,都有Dispose方法,它的意思就是釋放當前對象,而我們在使用它們時,如何把非托管與托管對象結合起來,一起把對象釋放呢,這就是現在要說的Dispose模式

   /// <summary>
    /// 實現IDisposable,對非托(tuo)管系(xi)統(tong)進(jin)行資(zi)源(yuan)回收(shou)
    /// 作者:倉儲大叔
    /// </summary>
    public abstract class DisposableBase : IDisposable
    {
        /// <summary>
        /// 標準(zhun)Dispose,外界可以直接調用它(ta)
        /// </summary>
        public void Dispose()
        {
            Logger.LoggerFactory.Instance.Logger_Debug("Dispose");

            this.Dispose(true);////釋放托管(guan)資源
            GC.SuppressFinalize(this);//請(qing)求(qiu)系統(tong)不要調(diao)用指定對象的(de)終(zhong)結(jie)器. //該方法在對象頭中(zhong)設置一個(ge)(ge)位,系(xi)統在調用終結器時將檢查這個(ge)(ge)位
        }

        private void Dispose(bool disposing)
        {
            if (!_isDisposed)//_isDisposed為false表示沒有進行(xing)手動dispose
            {
                //清(qing)理(li)托管(guan)資源和清(qing)理(li)非(fei)托管(guan)資源
                Finalize(disposing);
            }
            Logger.LoggerFactory.Instance.Logger_Debug("Dispose complete!");
            _isDisposed = true;
        }

        /// <summary>
        /// 由子類自己(ji)去實現自己(ji)的Dispose邏輯(ji)(清(qing)理(li)托(tuo)管和(he)非托(tuo)管資(zi)源)
        /// </summary>
        /// <param name="disposing"></param>
        protected abstract void Finalize(bool disposing);

        private bool _isDisposed;

        /// <summary>
        /// 是否完成了資(zi)源的釋放
        /// </summary>
        public bool IsDisposed
        {
            get { return this._isDisposed; }
        }
        /// <summary>
        /// 析構方法-在(zai)類被釋(shi)放前(qian)被執行
        /// </summary>
        ~DisposableBase()
        {
            Logger.LoggerFactory.Instance.Logger_Debug("析構方法");

            //執行到這里,托管(guan)資源已經被(bei)釋放
            this.Dispose(false);//釋放非(fei)托管(guan)資(zi)源,托管(guan)資(zi)源由終極(ji)器自(zi)己(ji)完成(cheng)了(le)
        }
    }

使用它

  public class ZzlTools : DisposableBase
    {

        protected override void Finalize(bool disposing)
        {
            if (!disposing)
            {
                //清(qing)除托管
            }
            //清理(li)非托管
        }
    }

通(tong)過(guo)大叔整理的(de)Dispose基類,我們可(ke)以看到,外界的(de)對(dui)(dui)象只要實現Finalize方法(fa)即可(ke),把自己(ji)需要釋放的(de)對(dui)(dui)象寫(xie)在Finalize里就行了,簡單(dan)!

最后,和大(da)家分享我(wo)的一(yi)個經驗,學習基礎知識,就(jiu)像修煉內功,我(wo)們一(yi)定(ding)要打好根基,才能更上一(yi)層(ceng)樓!

謝謝閱讀!

回到目錄 

 

posted @ 2016-04-15 15:00  張占嶺  閱讀(1829)  評論(5)    收藏  舉報