棧內存就像一系列堆得越來越高的箱子。調用方法是,它的每一個參數都被放入一個箱子,並將這個箱子放到棧的最頂部。每個局部變量也同樣分配到一個箱子,並同樣放到棧的最頂部。方法結束後,它的所有箱子都從棧中移除。
堆上存儲的有:引用類型的“對象”,可空類型。
堆內存則像散布在房間裡的一大堆箱子,而不像棧那樣每個箱子都嚴格地堆在另一個箱子上面。每一個箱子都有一個標簽,它標記了這個箱子是否正在使用。創建一個新對象時,runtime 會查找一個空箱子,並把它分配給對象。對對象的引用則存儲在棧上的一個局部變量中。runtime 將跟蹤每個箱子的引用數量(有多個變量引用同一個對象)。一旦最後一個引用消失,runtime 就將箱子標記為“未使用”。將來某個時候,會清除箱子裡的東西,使之能被真正重用。
另外,堆內存是一種有限資源,如果被耗盡,new 操作符將拋出一個OutOfMemoryException ,對象將創建失敗。
代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace stack_heap
{
class Program
{
static void Main(string[] args)
{
}
void Method(int param)
{
Circle c;
c = new Circle(param);
}
}
class Circle
{
public Circle(int a)
{
}
}
}
調用Method 方法時,並給param 傳遞實參為8 後:
1、首先,棧中將分配一小片內存(剛好能存儲一個int),並用值8 來初始化。
2、在方法內部,還要從棧中分配出另一小片內存,它剛好能夠存儲一個引用(一個內存地址),只是暫時不進行初始化(它是為Cricle 類型的變量c 准備的)。
3、接著從堆中分配一個足夠大的內存區域來容納一個Circle 對象。
PS:new 關鍵字執行的操作--- 它運行Circle 構造器,將這個原始的堆內存轉換成一個Circle 對象