堆和栈在操作系统的底层实现

堆和栈的区别

堆是可用于动态分配的内存区域,由程序员手动管理(或是垃圾回收机制管理)。
栈用于管理函数调用,局部变量等的高效内存区域,由操作系统自动管理。

32位系统中,进程的虚拟内存空间分布如下,栈从高地址向低地址延伸,堆从低地址向高地址分配。

栈在操作系统的底层实现:

1、线程创建的时候,操作系统将为其分配1MB的栈空间(Windows系统默认)。
2、栈的使用:只需要移动栈指针。
3、x86平台下rsp为栈顶指针,rbp为栈底指针。(注意:栈从高地址向低地址延伸)。
4、进程栈(主线程栈)在进程启动时创建。
5、操作系统管理:
(1)函数调用时先将参数压栈(先放寄存器rcx,rdx,r8,r9,call进去后参数压栈),
(2)执行call指令,将返回地址(上一级函数的下一条指令地址)压栈,
(3)创建栈帧,保存上一级函数的栈底指针,设置rbp为新函数的栈底,
(4)为局部变量分配空间(注意数据对齐,数据所在的内存地址是数据长度的整数倍),
(5)最后还原栈底指针,栈顶指针,ret指令弹出返回地址。

64位系统一个int占4字节,后续写文章全部总结一遍。

堆在操作系统的底层实现

1、小块内存分配(小于阈值,例如128KB)

  • malloc维护多个arena,每个arena包含一个或多个内存块。
  • 分配请求首先尝试从现有的arena中分配内存。
  • 如果arena中没有足够的可用内存,malloc可能会扩展现有的arena(可能需要调用 brk或sbrk),或者创建一个新的 arena。
  • 释放的内存通常不会立即返还给操作系统,而是保留在arena中,以便后续的分配请求可以重用这些内存。

2、大块内存分配(大于或等于阈值)

  • malloc使用mmap系统调用分配匿名内存。
  • 释放的内存通过munmap系统调用返还给操作系统。
  • 注意:mmap通常用于将文件内容映射到内存中,但它也可以用于分配匿名内存(即不与任何文件关联的内存)。

问题:

Q:栈为什么适合函数调用?
A:先进后出,具有严格的顺序,函数嵌套调用不会混乱,1234调用,4321释放。

Q:当函数递归调用过深时会发生什么?
A:栈溢出,触发SIGSEGV信号,程序崩溃。

Q:为什么栈的分配速度比堆快?
A:栈只需要移动指针,堆需要查找空闲块,处理碎片和系统调用。

Q:多线程程序当中,堆和栈如何实现隔离?
A:栈是线程私有,堆是进程共享,需要同步机制加锁。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇