線程堆棧:簡稱棧 Stack 托管堆: 簡稱堆 Heap
使用.Net框架開發(fā)程序的時候,我們無需關心內存分配問題,因為有GC這個大管家給我們料理一切。如果我們寫出如下兩段代碼: 代碼段1:
public int AddFive(int pValue) { int result; result = pValue + 5; return result; }
代碼段2:
public class MyInt { public int MyValue; }
public MyInt AddFive(int pValue) { MyInt result = new MyInt(); result.MyValue = pValue + 5; return result; }
問題1:你知道代碼段1在執(zhí)行的時候,pValue和result在內存中是如何存放,生命周期又如何?代碼段2呢? 要想釋疑以上問題,我們就應該對.Net下的棧(Stack)和托管堆(Heap)(簡稱堆)有個清楚認識,本立而道生。如果你想提高程序性能,理解棧和堆,必須的! 本文就從棧和堆,類型變量展開,對我們寫的程序進行庖丁解牛。 C#程序在CLR上運行的時候,內存從邏輯上劃分兩大塊:棧,堆。這倆基本元素組成我們C#程序的運行環(huán)境。
一,棧 vs 堆:區(qū)別?
棧通常保存著我們代碼執(zhí)行的步驟,如在代碼段1中 AddFive()方法,int pValue變量,int result變量等等。而堆上存放的則多是對象,數據等。(譯者注:忽略編譯器優(yōu)化)我們可以把棧想象成一個接著一個疊放在一起的盒子。當我們使用的時候,每次從最頂部取走一個盒子。棧也是如此,當一個方法(或類型)被調用完成的時候,就從棧頂取走(called a Frame,譯注:調用幀),接著下一個。堆則不然,像是一個倉庫,儲存著我們使用的各種對象等信息,跟棧不同的是他們被調用完畢不會立即被清理掉。
如圖1,棧與堆示意圖
棧內存無需我們管理,也不受GC管理。當棧頂元素使用完畢,立馬釋放。而堆則需要GC(Garbage collection:垃圾收集器)清理。
二,什么元素被分配到棧?什么被分配到堆?
當我們程序執(zhí)行的時候,在棧和堆中分配有四種主要的類型:值類型,引用類型,指針,指令。
值類型: 在C#中,繼承自System.ValueType的類型被稱為值類型,主要有以下幾種(CLR2.0中支持類型有增加): * bool * byte * char * decimal * double * enum * float * int * long * sbyte * short * struct * uint * ulong * ushort
引用類型: 以下是引用類型,繼承自System.Object: * class * interface * delegate * object * string
指針: 在內存區(qū)中,指向一個類型的引用,通常被稱為“指針”,它是受CLR( Common Language Runtime:公共語言運行時)管理,我們不能顯示使用。需要注意的是,一個類型的引用即指針跟引用類型是兩個完全不同的概念。指針在內存中占一塊內存區(qū),它本身只代表一個內存地址(或者null),它所指向的另一塊內存區(qū)才是我們真正的數據或者類型。
新聞熱點
疑難解答