盡管在.Net framework中我們不太需要關注內存管理和垃圾回收這方面的問題,但是出於提高我們應用程序性能的目的,在我們的腦子裡還是需要有這方面的意識。明白內存管理的基本行為將有助於我們解釋我們程序中變量是如何操作的。在本文中我將討論棧和堆的一些基本知識,變量的類型和某些變量的工作原理。
當你在執行程序的時候內存中有兩個地方用於存儲程序變量。如果你還不知道,那麼就來看看堆和棧的概念。堆和棧都是用於幫助我們程序運行的,包含某些特殊信息的操作系統內存模塊。那麼堆和棧有什麼不同呢?
堆VS棧的區別
棧主要用於存儲代碼,自動變量等信息;而堆則主要用於存儲運行期生成的對象等信息。將棧看作是一個有著層級關系的盒子,我們每一次只能操作盒子最上一格的東西。這也就是棧先進後出的數據結構特性。因此棧在我們程序中主要是用於保存程序運行時的一些狀態信息。堆則主要是用於保存對象內容,以便我們能夠在任何時候去訪問這些對象。總的來說,堆就是一種數據結構,我們不需要通過一套規則,可以隨時訪問的內存區域;棧則總是依據先進後出的,每次只能訪問最頂層元素的內存區域。下面是個示意圖:
由於棧的特性所至,所以棧具有自我維護性,棧的內存管理可以通過操作系統來完成。而堆的管理就需要通過GC(垃圾回收器)來完成,使用一定的算法來掃描並釋放沒有用的對象。
關於棧和堆的更多內容
我們代碼中有四種主要的類型需要存儲在棧和堆當中:值類型,引用類型,指針和程序指令。
值類型:
在c#中主要的值類型有:
bool ,byte ,char ,decimal ,double ,enum ,float ,int ,long ,sbyte ,short ,struct ,uint ,ulong ,ushort都來自於System.TypeValue。引用類型:
在C#中主要的引用類型有:class, interface, delegate,object,string所有的引用類型都繼承自System.Object。指針:在我們的內存管理中一個指針的意義就是一個引用對應到一個類型上。在.Net framework中我們不能顯式的使用指針,所有的指針都被通用語言運行時(CLR)管理。指針是一塊指向其他內存區域的內存區域。指針需要占據一定的內存空間就像其他任何數據一樣。
指令:指令就是計算機執行代碼,如函數調用或是數據運算等。 內容和地址的問題
首先有兩點需要說明:
1.引用類型總是存在於堆裡 – 很簡單,但是完全正確嗎?
2.值類型和指針總是出現在他們聲明的地方。這個有點復雜需要相關的棧工作原理的知識。
棧就像我們之前提到的那樣,記錄我們程序執行時的一些信息。當我們在調用一個類的方法時,操作系統將調用指令壓棧並附帶方法參數。然後進入函數體處理變量操作。這個可以用下面的代碼來解釋:
public int AddFive(int pValue) {
int result;
result = pValue + 5;
return result;
}