操作系统中的堆和栈

都指的是内存空间。

1.内存分配方式

栈:

  • 自动分配和释放:由编译器自动管理,函数调用时分配局部变量和参数,函数结束时自动释放。
  • 线性结构:内存按后进先出的顺序操作,仅通过移动栈顶指针完成分配和释放。

堆:

  • 手动管理:通过代码去申请和释放,在c语言中使用malloc去申请内存,使用free去释放。在C#中使用New去申请内存,通过垃圾回收器去释放内存
  • 动态分配:内存块按需分配,需要维护复杂结构(如空闲链表)来管理碎片。

2.栈与堆中数据的生命周期

栈:

  • 短暂:变量生命周期与函数调用绑定,函数结束集销毁。
  • 确定性:无需担心内心泄露。

堆:

  • 持久:内存生命周期有程序员控制, 可以跨函数或线程存在。
  • 风险:过早释放可能引发野指针,忘记释放会导致内存泄漏。

3.大小区别

栈:

  • 固定且较小:通常默认几MB(Linux默认8MB)递归过深(或无法结束)或大局部变量易导致溢出 Stack Overflow。

堆:

  • 灵活且较大:收物理内存和系统现在,可分配空间远大于栈。

4.访问速度

栈:

  • 高效:连续内存空间,仅需要移动指针,没有碎片问题,CPU缓存命中率高。

堆:

  • 较慢:需要动态去查找可用内存块,在频繁分配和释放不同大小的内存块会导致碎片可能触发碎片整理或系统调用 (如brk,sbrk)

5.线程与安全

栈:

  • 线程私有:没有线程拥有独立的栈,数据无需同步机制,天然线程安全。

堆:

  • 线程共有:所有线程共享,需同步机制(如锁)避免竞态条件。

6.典型用途

栈:

  • 因为栈高效但有限,适合小数据,短生命周期 如函数调用,局部变量

堆:

  • 灵活但管理复杂,适合大数据或长生命周期。如动态数据结构链表,树,

CPU命中率:是衡量CPU缓存效率的重要核心指标,表示CPU在缓存中找到所需数据的概率。