linux - 为什么可以在不事先分配内存的情况下使用堆栈?

标签 linux memory stack

进程的虚拟地址空间以text开头, databss过程的片段。放置此堆分配后,堆会向更大的内存地址增长。但是,在使用堆的一部分之前,必须分配一个内存块(valloc 等),否则将分配一个 segfault。发生(或应该发生)。

堆栈从虚拟地址空间中的初始大地址向较小的值增长。据我所知,这在没有虚拟内存分配的情况下有效。如果在堆的情况下这是不可能的,那么如何在没有事先分配内存的情况下使用堆栈? (它是相同的线性虚拟地址空间。)

据我所知alloca就像sub esp, <size>一样实现.但是堆栈正在使用的虚拟地址空间区域必须在此之前以某种方式分配,对吧?

最佳答案

以某种方式出现段错误。这是一种“惰性”优化。只要外部无法观察到差异,操作系统就会尽可能多地作弊。

但是,陷阱不会像正常的段错误那样导致生成信号(默认情况下会终止进程)。相反,操作系统会验​​证未超过允许的线程大小,然后从零池中拉取一个新页面。

在 Windows 下,该机制被奇特地命名为“保护页面”,我不知道在 Linux 下有类似的命名。无论哪种方式,保护页在技术上不过是写保护页(或不存在的页),操作系统将其记住为“特殊”页,因此当它被触摸时会发生一些特定的操作。

这与动态分配(malloc,它调用 sbrk)的工作方式也非常相似。当您分配内存时,只要您不访问分配的内存,就不会发生太多事情。唯一发生的事情是操作系统“记住”您增长了数据段。
如果现在发生故障,操作系统将创建该页面,或者分别从零池中拉出它,并假装它一直在那里。您永远不知道它以前不存在。

关于linux - 为什么可以在不事先分配内存的情况下使用堆栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11614451/

相关文章:

bios中断调用所需的堆栈大小

c++ - 这个堆栈有什么问题?

html - 图 slider "Stacks"

linux - 如何设置终端标题以在运行时显示当前正在运行的命令,并在完成后将其显示在括号中?

linux - 通过 Dropbox 在 linux 上远程执行命令?

python - Selenium 网格 - Python 文件路径

java - 指定使用引用初始化类和不使用引用初始化类之间的区别

linux - Bash循环比较文件

android - View 引用成员变量和局部变量的区别

Java ImageIO 将图像 byte[] 读取到预分配的 BufferedImage 中