.NET對象與Windows控制代碼(一):控制代碼的基本概念

來源:互聯網
上載者:User

標籤:讀寫   asp   管程   dip   建立對象   pen   .com   nat   記憶體   

在.NET編程中,得益於有效記憶體管理機制,對象的建立和使用比較方便,大多數情況下我們無須關心對象建立和分配記憶體的細節,也可以放心的把對象的清理交給自動記憶體回收來完成。由於.NET類庫對系統底層對象進行了封裝,我們也不需要調用Windows API來操作非託管對象。但不直接操作非託管對象,並不意味著程式不會間接建立這些對象,如果不瞭解.NET對象與非託管資源的關係,我們很有可能因為不恰當的使用這些託管對象,而導致非託管資源流失。本文嘗試說明Windows對象和控制代碼的基本概念,以及.NET編程中的對象與它們的關係,並結合一些簡單的樣本程式來探討控制代碼泄露的話題。

一、什麼是控制代碼?

Windows編程中,程式需要訪問各種各樣的資源,如檔案、網路、視窗、表徵圖和線程等。不同類型的資源被系統封裝成不同的資料結構,當需要使用這些資源時,程式需要依據這些資料結構建立出不同的對象,當操作完畢並不再需要這些對象時,程式應當及時釋放它們。在Windows中,應用程式不能直接在記憶體中操作這些對象,而是通過一系列公開的Windows API由對象管理器(Object Manager)來建立、訪問、跟蹤和銷毀這些對象。當調用這些API建立對象時,它們並不直接返回指向對象的指標,而是會返回一個32位或64位的整數值,這個在進程或系統範圍內唯一的整數值就是控制代碼(Handle)。隨後程式再次訪問對象,或者刪除對象,都將控制代碼作為Windows API的參數來間接對這些對象進行操作。在這個過程中,控制代碼作為系統中對象的標識來使用。

對象管理器是系統提供的用來統一管理所有Windows內部對象的系統組件。這裡所說的內部對象,不同於進階程式設計語言如C#中“對象”的概念,而是由Windows核心或各個組件實現和使用的對象。這些對象及其結構,要麼不對使用者代碼公開,要麼只能使用控制代碼由封裝好的Windows API進行操作。C#編程中,多數情況下,我們並不需要與這些Windows API打交道,這是因為.NET類庫對這些API又進行了封裝,但我們的託管程式仍然會間接建立出很多Windows內部對象,並持有它們的控制代碼。

如上所說,控制代碼是一個32位或64位的整數值(取決於作業系統),所以在32位系統中,C#完全可以用int來表示一個控制代碼。但.NET提供了一個結構體System.IntPtr專門用來代表控制代碼或指標,在需要表示控制代碼,或者要在unsafe代碼中使用指標時,應當使用IntPtr類型。

二、C#中建立檔案控制代碼的過程

舉例來說,檔案屬於一種非託管的系統資源。在C#中,可以用File類的靜態方法Open來得到一個FileStream對象,來對磁碟檔案進行讀寫操作。FileStream對象本身是託管對象,它是如何與檔案這個非託管資源產生聯絡的呢?

 

大致說來,C#中開啟檔案的操作會經過下列步驟:

  1. 調用.NET靜態方法System.IO.File.Open時,File類會建立一個FileStream對象並傳入必要的參數,如檔案路徑,FileMode和FileAccess選項。FileMode枚舉表明是希望建立新檔案,開啟已有檔案,覆蓋原有檔案或是在原檔案上追加新內容;FileAccess枚舉表明是希望讀檔案、寫檔案或兩者都有。
  2. 接著FileStream調用自己的Init方法進行初始化,在這個過程中,有更多細節需要考慮。為了建立一個檔案,初始化方法需要更多額外的資訊和檢查,比如本進程在使用檔案時是否允許其它進程讀寫檔案,檔案路徑是否有效,是否有足夠的許可權,目標檔案是否是允許被訪問的檔案類型,是否正確設定了FileMode和FileAccess選項的組合等。
  3. 完成這些必要的檢查後,FileStream.Init調用Win32Native.SafeCreateFile方法。
  4. Win32Native類封閉了大量的Windows API,SafeCreateFile方法以P/Invoke的方式調用kernel32.dll中的CreateFile API,並返回SafeFileHandle。SafeFileHandle是一個有趣的類型,繼承自SafeHandle,包含了真正的IntPtr類型的檔案控制代碼。.NET的設計者有意讓這個控制代碼欄位對外不可見,但如果你非要拿到這個控制代碼值,SafeFileHandle也提供了DangerousGetHandle()方法滿足你的要求:都告訴你Dangerous了,你自己看著辦。
  5. 包含著檔案控制代碼的SafeFileHandle會被返回並存放在FileStream對象中。隨後的讀取和寫入操作,FileStream都會使用這個控制代碼與Windows API進行互動,直到最終關閉控制代碼。至始至終,我們的代碼都無需直接關心控制代碼的存在,FileStream負責了絕大部分工作。

三、通過控制代碼操作對象的好處

Windows不允許應用程式直接存取記憶體中更底層的對象,而是由對象管理器統一管理,總的來說,至少有以下好處:

  1. 在作業系統層面上,為所有程式使用系統資源提供了統一的介面和機制。如果沒有對象管理器,不同程式會有各種各樣的實現方式來訪問資源,並且這些代碼散落在各種,難以規範,也無從協調解決資源的爭用。
  2. 將需要在系統層級保護的對象隔離起來,提供更高安全性。
  3. 所有對系統關鍵資源的訪問都經由對象管理器,使得系統可以方便的追蹤和限制資源的使用,進行許可權控制。

四、查看進程的控制代碼計數

到現在為止,本文討論的全是看不見的概念,有必要來直觀的看一下系統中的控制代碼使用方式。有多種方式可以查看進程的控制代碼使用方式,先從兩個工具開始,Windows工作管理員和Process Explorer。

工作管理員預設不顯示控制代碼數,需要在“查看”-“選擇列”中勾選“控制代碼數”後,才會顯示進程中當前開啟的控制代碼計數。如所示,可以看到記事本進程當前開啟59個控制代碼。

 

系統內建的工作管理員查看控制代碼計數很方便,但如果想知道這些控制代碼具體是什麼,可以使用Process Explorer。Process Explorer是Windows Sysinternals工具包中的一個進程查看器,可以從這裡下載。如果你看到的視圖跟不同,可以點擊View,選中Show Lower Pane,並在Lower Pane View中選擇Handles。在列表中選擇進程後,下方面板中會顯示該進程中控制代碼的詳細列表。

 

五、為什麼關注控制代碼數

控制代碼指向的是諸如視窗、線程、檔案、菜單、進程和定時器之類的系統資源,和所有被稱為“資源”的事物一樣,稀缺性是它們共同的特點。對於電腦和作業系統來講,記憶體是一種稀缺資源,而所有的控制代碼和對象都儲存在記憶體中。基於這個事實,作業系統不允許進程無限制的建立對象和控制代碼。對於工作管理員中的“控制代碼數”來講,每一進程允許開啟的控制代碼數理論上來講可達2^24個,但由於記憶體的限制,實際數字大打折扣。在我的測試中,32位的.NET進程“控制代碼數”在達到1500萬以上後,程式開始出現各種各樣的問題。事實上絕大多數程式不會使用到這麼多控制代碼,除非特殊需要,在軟體編程中,如果自己的程式“控制代碼數”上千甚至是幾千時,就需要引起特別注意,這一般說明程式中已經存在控制代碼泄露的情況。

你可能已經留意到,本文前面工作管理員中,除了顯示進程的“控制代碼數”之外,還顯示了“使用者物件”和“GDI對象”的數量,它們屬於另外兩種控制代碼。具體的區別我們將在後面介紹,現在我們需要清楚的是,系統對於這兩種對象同樣設定了數量限制。對於“使用者物件”和“GDI對象”來說,每個進程允許建立的數量上限是在註冊表中設定的,分別是HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows中的USERProcessHandleQuota項和GDIProcessHandleQuota項,在Windows 7的32位作業系統上,兩個項都被預設設定為10000。你可以更改這個設定,使用者物件最多隻能設定為18000個,GDI對象最多為65536個。但是改變這個設定是不被推薦的,一般情況下當你的應用程式需要用到超過10000個使用者物件或GDI對象時,應該首先檢查哪裡出現了控制代碼泄露,而不是更改上限數量;另一方面,更改上限並不意味著應用程式就真的可以建立和使用這麼多個物件控制代碼,實際可用的數量同時受制於當前系統可用記憶體。

引用:http://www.cnblogs.com/silverb/p/5300255.html

.NET對象與Windows控制代碼(一):控制代碼的基本概念

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.