簡體   English   中英

托管代碼和非托管代碼,內存和大小有什么區別?

[英]What is the difference in managed and unmanaged code, memory and size?

在看到和聽取很多關於托管和非托管代碼之后,並且知道唯一的區別是托管是關於CLR而非托管是在CLR之外,這讓我非常好奇地了解它。 它是什么,托管和非托管代碼,內存和大小?

我在C#中編寫的代碼如何是非托管的,而這是C#代碼,以及大小的內存如何變得不受管理。 一個例子和一點點見解會有所幫助。

簡短回答:

  • 托管代碼是您編寫並編譯為.NET CIL的 .NET代碼(VB.NET,C#等)。
  • 非托管代碼是不在.NET下編譯為直接機器代碼的代碼。

答案很長:

什么是托管代碼?

托管代碼是Visual Basic .NET和C#編譯器創建的代碼。 它編譯為中間語言(IL),而不是編譯可以直接在您的計算機上運行的代碼。 CIL保存在一個名為程序集的文件中,同時還包含描述您創建的代碼的類,方法和屬性(如安全性要求)的元數據。 這個程序集是.NET世界中部署的一站式購物單元。 您將其復制到另一台服務器以在那里部署程序集 - 通常復制是部署中唯一需要的步驟。

托管代碼在公共語言運行時中運行。 運行時為運行的代碼提供各種服務。 在通常的事件過程中,它首先加載並驗證程序集以確保CIL正常。 然后,就在調用方法時,運行時會安排將它們編譯為適合運行程序集的機器的機器代碼,並緩存此機器代碼以在下次調用方法時使用。 (這稱為Just In Time,或JIT編譯,或者通常只是Jitting。)

隨着程序集的運行,運行時繼續提供諸如安全性,內存管理,線程等服務。 應用程序由運行時管理。

Visual Basic .NET和C#只能生成托管代碼。 如果您正在使用這些應用程序,那么您正在制作托管代碼。 如果您願意,Visual C ++ .NET可以生成托管代碼:創建項目時,選擇名稱以.Managed。開頭的應用程序類型之一,例如.Managed C ++應用程序。

什么是非托管代碼?

非托管代碼是您在Visual Studio .NET 2002發布之前使用的代碼。 Visual Basic 6,Visual C ++ 6,哎呀,即使是15年前的C編譯器,你可能仍然在你的硬盤驅動器上所有產生的非托管代碼。 它直接編譯為在您編譯它的機器上運行的機器代碼,並且只要它們具有相同的芯片或幾乎相同,就可以在其他機器上編譯。 它沒有從不可見的運行時獲得安全性或內存管理等服務; 它從操作系統中獲取它們。 而且重要的是,它通過調用Windows SDK中提供的API,通過詢問它們來明確地從操作系統中獲取它們。 最近的非托管應用程序通過COM調用獲得了操作系統服務。

與Visual Studio中的其他Microsoft語言不同,Visual C ++可以創建非托管應用程序。 當您創建項目並選擇名稱以MFC,ATL或Win32開頭的應用程序類型時,您將創建一個非托管應用程序。

這可能會導致一些混淆:當您創建.Managed C ++應用程序時,構建產品是具有.exe擴展名的CIL程序集。 創建MFC應用程序時,構建產品是本機代碼的Windows可執行文件,也具有.exe擴展名。 兩個文件的內部布局完全不同。 您可以使用中間語言反匯編程序ildasm查看程序集內部並查看元數據和CIL。 嘗試將ildasm指向一個非托管的exe,你會被告知它沒有有效的CLR(公共語言運行時)標頭,並且不能被反匯編 - 相同的擴展名,完全不同的文件。

Native Code怎么樣?

短語本機代碼用於兩個上下文中。 許多人將它用作非托管代碼的同義詞:使用舊工具構建的代碼,或在Visual C ++中故意選擇的代碼,它不在運行時運行,而是在機器上本機運行。 這可能是一個完整的應用程序,或者它可能是使用COM Interop或PInvoke從托管代碼調用的COM組件或DLL,這兩個強大的工具可確保您在遷移到新世界時可以使用舊代碼。 我更喜歡說.unmanaged代碼。 對於這個含義,因為它強調代碼不能獲得運行時的服務。 例如,托管代碼中的代碼訪問安全性可防止從其他服務器加載的代碼執行某些破壞性操作。 如果您的應用程序調用從另一台服務器加載的非托管代碼,您將無法獲得該保護。

短語本機代碼的另一個用途是描述JIT編譯器的輸出,即在運行時實際運行的機器代碼。 它是管理的,但它不是CIL,它是機器代碼。 因此,不要只假設native = unmanaged。

來源

這可能是一個很長的答案,討論C編譯器生成的機器代碼與JIT編譯器從托管程序生成的機器代碼之間的許多細微差別。 足夠長,真的需要一本書,但這些書已經寫好了。 傑弗里里希特的任何東西。

我會保持簡短和活潑,因為所有這些微妙的差異歸結為一個規則:

托管代碼是從垃圾收集堆中分配內存的代碼。

托管代碼在應用程序域中運行,非托管代碼在操作系統的進程下運行。

通常,托管代碼具有比等效編寫良好的非托管(本機)代碼更高的運行時內存占用量。

在OS下直接運行的應用程序稱為

未托管的應用

而在.net框架下運行的應用程序被稱為

托管應用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM