程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .Net托管資源非托管資源垃圾回收的疑問

.Net托管資源非托管資源垃圾回收的疑問

編輯:關於.NET

CLR為開發者提供了一個非常讓人激動的功能--垃圾回收。但是園子裡關於垃圾回收的討論,大多是討論垃圾回收的原理,以及Dispose模式。但是垃圾回收在實際使用時,是不是可以達到其設計的目標,在開發過程中有沒有需要注意的問題呢?本人也不是非常明確,這篇文章希望能達到拋磚引玉的效果,希望個人牛人能夠給本人或同樣存在疑惑的人一個清楚明確的答案。

什麼是垃圾回收?就是說你在使用CLR的時候(不包含托管資源) ,只需要new一個對象使用。而不需要通過程序代碼進行釋放對象(以上是本人理解的垃圾回收的意義)。

托管資源 非托管資源

托管資源和非托管資源的區別通常會讓開發者弄不清楚,到底什麼是托管的,什麼不是托管的。這裡說一下自己的體會。如果你使用的Class是屬於CLR的,不管它實際上使用的什麼資源。CLR都會幫你進行垃圾回收。簡單的比如一個List對象,你使用完成(變量脫離其作用域)就會被CLR自動回收。那麼對於網上常說的數據連接,文件類呢?其實同樣會在使用完成後被自動回收,但是因為此類資源很重要,而垃圾回收的時機不確定。所以很多教材上說此類資源需要在使用完成後及時釋放(通過程序代碼)。這裡說明一點就是CLR的Class都會被自動回收,無論它實際控制的是托管資源還是非托管資源。

這裡可以做一個簡單的測試,一個WinForm項目,兩個Button(button1, button2) ,點擊事件如下。

private void button1_Click(object sender, EventArgs e)

{

FileStream file = new FileStream(@"c:\DisposeTest.txt", FileMode.Open);

}

private void button2_Click(object sender, EventArgs e)

{

GC.Collect();

}

連續點擊button1,第二次就會報錯,說明文件沒有被釋放。但是如果點擊button1再點擊button2再點擊button1那麼就不會報錯了,因為button2垃圾回收將文件釋放了。

那麼哪些資源,對象是不能自動回收,必須通過程序代碼釋放的呢?簡單的說你使用的Class, 組件不屬於CLR。比如Win32API,Com組件等。使用上述類型的時候,如果分配了資源,那麼一定要通過代碼進行釋放。還是文件打開的例子,如果是使用 Win32API打開文件,那麼使用垃圾回收是沒有辦法釋放資源的。所以一定要在代碼中進行相關資源的釋放。

垃圾回收在開發中的問題 

托管資源,非托管資源已經說清楚了。垃圾回收的原理這裡就不說了,網上很多文章介紹。下面我們說一下在實際開發過程中是不是可以完全相信垃圾回收,而不需要考慮對象的釋放呢?或者哪些對象是需要及時釋放的呢?本人主要是是從事WinForm開發。所以下面的討論可能是以WinForm為背景。 一下是目前本人明確或者未明確的內容希望與大家討論。

1)哪些資源需要及時釋放?這個問題很明確了,數據庫連接,文件,還有其他的大家補充吧。就想到這麼多。

2)WinForm背景下,如果創建的Form被釋放(Form = null)的時候,Form內的字段(比如,String, DataTable, 其他自定義類)是否會被自動釋放(假設這些字段沒有被其他的地方引用)。

3)因為從事的是數據庫相關開發,自然用到最多的是ADO.Net,那麼除了Connection,其他的對象是否需要及時釋放,哪些對象是否需要及時釋放(這裡比較關心的是DataSet, DataTable)?

4)補充一點如果上述很多對象都需要及時釋放,那麼垃圾回收的意義是不是就一定程度的降低了呢?

以上是個人對垃圾回收的理解和疑問,希望大家能夠一起討論,最後能有明確的結論。

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