一、比方
- 栈(Stack)= 随身口袋 / 桌面空间小、拿放东西超快,用完随手清空,自己自动收拾,不用你管。
- 堆(托管堆 Managed Heap)= 大仓库空间超大、放大件东西,放进去慢,自己不会自动收拾,要等保洁阿姨(GC 垃圾回收)来清理。
二、栈 Stack(线程栈)
特点
- 自动分配、自动销毁进入方法就开辟空间,方法执行完立马清空。
- 速度极快,内存是连续的。
- 存放什么
- 局部值类型:int、double、bool、struct、DateTime
- 引用类型的地址(指针)(不是对象本身,只是仓库门牌号)
void Test() { int a = 10; // 直接放栈上 string s; // 栈上存一个地址位置,暂时没指向仓库 } // 方法结束 → 栈直接清空,a、s 全部消失一句话 栈就是临时工作台,方法用完就扔,自动清理。
三、托管堆
C# 里说的堆,默认就是托管堆。
特点
- 空间巨大,可以存很大、很多对象。
- 不会自动释放,靠GC 垃圾回收定时清理没人用的对象。
- 存放什么
new 出来的所有引用类型对象- class 实例、字符串、数组、集合 List 等真实本体数据
string s1 = "abc"; Person p = new Person(); 栈上:s1、p 只存地址编号
托管堆:真正存
"abc"字符串、Person 对象的所有数据
一句话
堆就是大仓库,放引用类型真实数据,GC 帮你打扫垃圾。
string s1 = "abc"; string s2 = s1; s2 = "def";内存全过程:
s1在栈上,存一个地址 → 指向托管堆里的"abc"s2 = s1:栈上复制地址,s1、s2 都指向堆里同一个"abc"s2 = "def":在托管堆新建"def",把 s2 栈上的地址改成新地址- s1 还指着老的
"abc",所以s1 不变
- s1 还指着老的
总结
| 特性 | 栈 Stack | 托管堆 Heap |
|---|---|---|
| 大小 | 小 | 超大 |
| 速度 | 极快 | 较慢 |
| 谁管理 | 系统自动,方法结束就清 | GC 垃圾回收定时清理 |
| 存什么 | 值类型、引用类型的地址 | new 出来的对象、字符串、数组本体 |
| 生命周期 | 随方法消失 | 没人引用了才被 GC 回收 |
值类型放栈上,用完自动亡;引用地址蹲栈上,对象本体住堆仓。