【轉】編寫高品質代碼改善C#程式的157個建議——建議53:必要時應將不再使用的對象引用賦值為null

來源:互聯網
上載者:User

標籤:不能   正是   靜態變數   佔用   線程   引用   使用   變數   col   

 

建議53:必要時應將不再使用的對象引用賦值為null

在CLR託管的應用程式中,存在一個“根”的概念,類型的靜態欄位、方法參數、以及局部變數都可以作為“根”的存在(實值型別不能作為“根”,只有參考型別的指標才能作為“根”)。

局部變數在代碼運行過程中會在記憶體中建立一個“根”。在一次記憶體回收中,記憶體回收行程會沿著線程棧上行檢查“根”(線程棧檢查完畢後,還會檢查所有的參考型別對象的靜態欄位的根集合)。當檢測到方法內的“根”時,如果發現沒有任何一個地方引用了局部變數,則不管是否已經顯式將其賦值為null,都意味著該“根”已經被停止。然後,記憶體回收行程會發現該根的引用為空白,同時標記該根可被釋放,這也代表著類型對象所佔用的記憶體空間可以被釋放。所以為局部變數指定為null絲毫沒有意義,方法的參數變數也是這種情況。

JIT編譯器是一個最佳化過的編譯器,無論我們是否在方法內將局部變數賦值為null,如下面語句:

            SampleClass c1=new SampleClass();            c1 = null;

中c1 = null;這句都會被忽略。如果我們將項目設定為Release模式,這句話根本不會被編譯進運行時內。

 

正是由於以上分析,很多人會認為將對象賦值為null完全沒有必要。但是,在另一種情況下,卻要注意及時地將變數賦值為null,那就是類型的靜態欄位。將類型對象賦值為null,並不意味著同時將類型的靜態欄位賦值為null。當類型對象被回收時,類型的靜態欄位卻沒有被回收。

 

之所以靜態欄位不被釋放(同時賦值為null語句也不會像局部變數那樣被運行時編譯器最佳化),是因為靜態欄位一旦被建立,該“根”就一直存在。所以,記憶體回收行程始終不會認為它是一個垃圾。非靜態欄位則不存在這樣一個問題。

 

在實際工作中,一旦我們感覺到自己的靜態參考型別參數佔用的記憶體空間比較大,並且用完後不會再使用,可以立即將其賦值為null。這也許並不必要,但這是一個好習慣。試想,如果一個系統中那些時不時在類中出現的靜態變數,它們那樣靜靜地待在記憶體中,一旦被建立,就永遠不會離開。所以,盡量少用靜態變數。

 

 

轉自:《編寫高品質代碼改善C#程式的157個建議》陸敏技

【轉】編寫高品質代碼改善C#程式的157個建議——建議53:必要時應將不再使用的對象引用賦值為null

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.