内存的堆、内存的栈有什么区别

栈(Stack) 是 “CPU 自动管理的临时工作台”,堆(Heap) 是 “程序员申请的大仓库”;
前者 随方法进出自动生死,后者 手动 or GC 清理,速度差一个数量级。

栈(Stack) 是 “CPU 自动管理的临时工作台”,堆(Heap) 是 “程序员申请的大仓库”;
前者 随方法进出自动生死,后者 手动 or GC 清理,速度差一个数量级。

一、生命周期:谁掌控生死?

表格
复制
场景
分配时机 方法调用 瞬间 CPU 压栈 new / malloc 时向操作系统申请
释放时机 方法 return 即弹出 手动 free / 垃圾回收 非确定
是否确定性 ✅ 编译期就定好 ❌ 运行期动态决定
典型例子
int x = 3; → 栈; new Person() → 堆。

二、速度差异:CPU 缓存 vs 系统调用

表格
复制
指标
分配/释放速度 1 条指令(移动 esp/rsp) 用户态→内核态→堆管理器,百条指令+锁
局部性 连续压栈,CPU 缓存友好 可能碎片化,缓存命中率低
并发成本 无锁 需 堆锁 or 线程局部分配
数量级:栈分配 纳秒级,堆分配 微秒级。

三、空间与限制

表格
复制
维度
默认大小 Windows 1 MB / Linux 8 MB 线程栈 仅受 进程地址空间 限制(2-128 GB)
大块数据 不宜(容易 StackOverflow) 适合 大对象、数组、字符串
碎片问题 无(先进后出) 有 → 需 压缩/整理

四、值类型 vs 引用类型 映射

csharp
复制
void Foo()
{
    int x = 10;              // 栈
    Point p = new Point();   // 栈(值类型)
    String s = new String(); // 引用本身在栈,**对象在堆**
}
 

五、一张图速记

复制
方法调用
┌---------┐
│ 参数    │ ← 栈顶
│ 返回地址│
│ 局部变量│
└---------┘  ← esp 自动上下移动 = 1 条指令

        ↓ new
┌-------------------------------┐
│          托管堆               │
│ Person  String  byte[] ...    │  GC 回收、可能碎片
└-------------------------------┘
 

六、金句

“栈由 CPU 自动压弹,方法结束即回收,速度快、空间小;
堆由 程序员或 GC 管理,生命周期灵活,空间大、速度慢、易碎片;
值类型和引用类型的 性能差异根源 就在于 栈 vs 堆 的分配策略。
posted @ 2025-10-15 09:44  yinghualeihenmei  阅读(8)  评论(0)    收藏  举报