2013年8月8日 星期四

小山的 C# 教學-第23課-Garbage Collection 垃圾回收

本課簡介

自從學了物件導向之後,我們了解如何使用 new 建立物件
但是大家是否想過物件要怎麼要刪除呢?

本課將會先稍微複習物件儲存與 reference 的概念
然後介紹 C# 強大的垃圾回收機制

教學影片

注意:影片有高畫質 720P 的選項,可以看得更清楚喔!



重點提示

1. 電腦的記憶體中有一塊空間稱為 Heap 來存放物件的本體

2. 當我們執行以下的程式碼後,電腦就會在 Heap 建立物件

new Student(...);
3. 當我們向下面宣告物件的變數時,只是產生一個用來記住物件地址的 Reference 而已

Student s;
4. C# 的程式執行時,背後有一個垃圾車會默默地檢查 Heap ,並刪除不需要的物件

5. 當一個物件沒有任何 reference 指向(儲存物件的地址)他的時候,就會被判定為不需要的物件

相關資訊連結

小山的 C# 教學-第16課-Value 與 Reference Type

http://slmtsite.blogspot.tw/2013/03/c-16-value-reference-type.html

維基百科 - 垃圾回收

http://zh.wikipedia.org/wiki/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6_%28%E8%A8%88%E7%AE%97%E6%A9%9F%E7%A7%91%E5%AD%B8%29

8 則留言:

  1. 我又來找碴了
    想請問一下小山老師
    封包是甚麼?封包的功用?
    跟一般的class不一樣嗎?
    一般的程式碼如何打包成封包?

    回覆刪除
  2. 封包?網路上的封包(Packet)嗎?

    回覆刪除
  3. 還是較封存?
    類似using AAA
    AAA.XXX();
    AAA這種東西要怎麼產生之類的

    回覆刪除
  4. 引用計數不是很慢嗎?
    如果自己判斷物件要不要移除應該會比較快吧

    回覆刪除
    回覆
    1. 確實比起 C/C++ 自己管理記憶體來說
      C# 採用的垃圾回收 (Garbage Collection, 簡稱 GC) 機制確實會多花費一些時間
      不過太多人寫 C/C++ 的程式遭遇到記憶體存取錯誤以及記憶體洩漏的困擾
      才有這種機制的誕生
      畢竟比起自己管理記憶體,有人幫你管理比較不容易出錯

      而且事實上,在經過實驗之後
      GC 機制對程式的影響並沒有想像中高
      因為它基本上是利用你電腦空閒的時間去處理
      所以這部分對於程式效能來說都不是大問題

      刪除
  5. 小山老師您好
    看了您解說的GC機制後,我有個疑問
    您影片中class的建立是在buuton的function內,離開了button,變數會失效GC機制就會啟動
    但若class的建立是使用全域變數的話,有辦法強制呼叫GC嗎??
    還是直接把實例的變數設為null即可然後等待GC??
    感謝指教

    回覆刪除
    回覆
    1. 首先要先了解 C# 內並沒有所謂的全域變數 (跟 C/C++ 不同)
      宣告在 class 內,method 外面的變數叫做 property (性質、屬性)
      宣告在 method 內的都是區域變數

      基本上只要把變數設為 null
      那個物件就會被自動標記為「可以被回收」的狀態
      仔細想一下就可以發現其實還蠻合理的
      因為如果你把所有指向該物件的變數設為 null,那你就不可能有辦法拿得回那個物件了
      因此回收車可以合理推斷它是該被回收的東西

      反過來說,如果還有變數指向物件的話
      那該物件就不會被回收
      這是 C# 物件導向的一種防禦機制
      在 C/C++ 中,物件必須要手動使用 free 來釋放記憶體
      而這個方法常常導致變數指向一些已經被釋放掉的東西
      進而產生寫 C/C++ 的人最討厭看見的「程式已停止回應」跟「Segmentation Fault」
      C# 藉由垃圾回收機制確保這件事情不會發生

      刪除
  6. 小山老師您好:
    目前我透過您寫的文章了解到了繼承篇,
    然後有在網路上練習看別人的程式碼,
    看到gcnew這個詞,
    可是不太了解他在做甚麼>< 謝謝您瞜,
    (還有我不太清楚這樣子的問題要留在哪比較合適,抱歉瞜)

    回覆刪除