程式執行時所有資料都要載入記憶體存放,資料佔用的空間與儲存位置由資料型別決定;程式執行期間會使用兩塊記憶體區域來存放資料:堆疊(Stack)、堆積(Heap)。
堆疊(Stack)
堆疊本質是一段連續記憶體陣列,遵循後進先出(LIFO)的資料結構,主要存放三類資料:
- 部分型別變數的數值
- 程式當下的執行上下文
- 傳入方法的參數

堆疊的記憶體分配與釋放全由系統自動控管,開發者不需手動操作;搞懂堆疊的底層運作邏輯,能更順利看懂程式執行流程與 C# 官方文件。
堆疊核心特性
- 僅能在堆疊頂端新增、刪除資料
- 往堆疊頂端存入資料:推入(Push)
- 從堆疊頂端取出資料:彈出(Pop)
堆疊記憶體特色
- 記憶體分配釋放速度極快,使用連續記憶體空間
- 生命週期綁定方法呼叫:方法執行完畢,堆疊框架自動銷毀
- 存放內容:實值型別變數、方法參數、區域變數、執行上下文

透過簡單範例,更容易理解堆積的運作方式
class Program
{
static void Main(string[] args)
{
int a = 10;
int b = 20;
int sum = Add(a, b);
}
static int Add(int x, int y)
{
return x + y;
}
}
Code language: JavaScript (javascript)
這段範例邏輯十分簡單:從程式入口 Main 函式第一行開始建立 int 型別變數 a,第二行建立變數 b,第三行呼叫 Add 函式並傳入 a、b 的數值進入函式內部。x 承接 a 的值、y 承接 b 的值,函式回傳 x 加 y 的運算結果,數值為 30 並送回呼叫處指派給 sum。Add 執行結束後 x、y 會從堆疊彈出,sum 數值更新為 30;Main 執行完畢後程式結束。下面我們一步步拆解整個堆疊推入、彈出的完整流程。
程式執行流程與堆疊推入彈出步驟





Add 執行完畢,x、y 屬於該函式內部的區域參數,必須依序彈出銷毀,釋放堆疊空間維持系統流暢。
彈出後 x、y 就不存在;Add 回傳的 30 送至呼叫處,準備指派給 sum。




各位讀者記住一個重點:函式執行時變數由上至下推入堆疊,順序為 a → b → 進入 Add → x → y;Add 結束 x、y 彈出,接著推入 sum;Main 結束後 sum、b、a 依反向順序彈出銷毀。
堆積(Heap)
堆積是一塊大型記憶體區域,用來配置記憶體區塊存放物件資料;和堆疊不同,堆積內的物件可任意順序新增、刪除。
程式無法手動刪除堆積內的物件,由 CLR(通用語言執行平台)的垃圾回收器 GC自動清理無任何參考、無法存取的孤立物件;省去其他語言手動釋放記憶體容易出錯的步驟。
堆積可以想像成一張大書桌,能隨意擺放各式物品;前面介紹的堆疊則像投幣筒,僅能單端進出資料。

GC 回收流程
- 程式在堆積建立三個物件,並持有有效參考
- 程式不再使用其中一個物件,該物件失去所有參考
- GC 偵測到無參考的孤立物件,釋放其佔用記憶體
- 回收完成,釋放的記憶體可重新配置給新物件使用
堆積記憶體特色
- 記憶體空間不連續,配置速度比堆疊慢
- 生命週期不受方法範圍限制,統一由 GC 管理
- 存放內容:參考型別實體(類別、陣列、委派等),堆疊只存放物件的記憶體位址
透過以下範例更直觀說明:前面提到基礎型別區域變數存在堆疊,而開發者自訂型別大多存放於堆積。請看範例程式:
class Program
{
static void Main(string[] args)
{
int a = 10;
int b = 20;
Student tom = new Student("Tom", 12);
Student lucy = new Student("Lucy", 12);
}
}
class Student
{
//成員變數
private string name;
private int age;
//建構函式,後續章節會詳細解說
public Student(string name, int age)
{
this.name = name;
this.age = age;
}
//成員方法
public void DisplayInfo()
{
Console.WriteLine($"Name: {name}, Age: {age}");
}
}
Code language: JavaScript (javascript)
下圖展示 Main 內四個變數 a、b、tom、lucy 的記憶體存放示意。和前面堆疊教學邏輯相同,程式由上至下執行,先推入 a、再推入 b,a 與 b 的數值直接存放在堆疊中。


舉例 tom 的資料存在堆積 00001 區塊,堆疊就儲存 00001 這個位址,後續可透過位址定位物件資料。
Main 執行完畢後,堆疊內 lucy: 01010 這個位址參考會彈出銷毀;但銷毀的只有位址資訊,堆積裡真正的物件資料依舊存在。此時堆積物件失去所有堆疊變數的參考記錄。


記憶體區域說明
堆疊、堆積都屬於軟體層次劃分的記憶體區段,並非實體硬體層面的分區。
堆疊與堆積只是軟體定義的邏輯記憶體區塊,實體記憶體硬體並沒有專屬標示「堆疊區/堆積區」的硬體模組。
實體記憶體 RAM 僅有統一的記憶晶片與連續實體位址,不存在任何區分堆疊、堆積的硬體標記
作業系統會為每個執行中的程式分配獨立虛擬記憶體空間,並預先將這塊虛擬記憶體切分為四大邏輯區段:
程式碼段:存放編譯後的程式指令
全域靜態段:靜態變數、常數
堆疊段(Stack):程式主執行緒、子執行緒各自獨立擁有專屬堆疊記憶體
堆積段(Heap):大型共享記憶池,動態配置記憶體
這裡提到的堆疊、堆積,僅是作業系統給行程劃分的邏輯區域,硬體層面並無隔離機制。
堆疊與堆積差異