【问题标题】:Is the heap preallocated for a process堆是否为进程预分配
【发布时间】:2020-12-06 14:28:31
【问题描述】:

自从我被引入进程堆的概念以来,我一直假设操作系统在创建进程时分配它。但后来我做了一些研究并阅读了一份声明here。 它说:

当程序向 malloc 请求空间时,malloc 请求 sbrk 增加堆大小并返回一个指向开始的指针 堆上的新区域。

如果我理解所说的话,操作系统会为进程的堆分配 0 个单元,并且只有通过调用 malloc 进程才能获得一些堆单元。对我来说,这更符合“动态分配”的说法。这是正确的吗?

【问题讨论】:

    标签: operating-system malloc heap-memory


    【解决方案1】:

    在图中你可以看到你的c/c++程序有一个空闲的内存区域,堆和堆栈可以增长直到填满该区域,所以初始堆是空的,当一个进程调用malloc时,通常(但在现代实现中,malloc 更喜欢总是调用mmap())他调用 sbrk() 函数来增加堆的内存大小(实际上他首先搜索空闲链表,如果没有他调用 sbrk() 的链表中的任何条目,请参阅此以获得 malloc() malloc implementation?) 的实现。 所以操作系统不会直接决定应该如何分配进程的堆,在 c/c++ 中,想法是这样工作的,但我认为在其他语言中,想法可能会略有不同。

    【讨论】:

    • 这个插图对于现代系统来说已经过时了:进程使用mmap 来从系统中获取内存块,而不是sbrk,这些内存块可能在堆栈之上具有虚拟地址。堆、堆栈、命令行参数和环境变量的布局是系统特定的。
    • 插图只是为了澄清这一点,但根据 man 文档 malloc 始终使用 sbrk() 分配小于 MMAP_THESHOLD 字节的内存块,否则使用 mmap
    • 您所指的man page 注释以Normally, 开头......它曾经使用malloc() 的旧实现来做到这一点,但现代倾向于使用mmap 来处理所有事情。跨度>
    • mhhh 好的,我明白了,但我不明白为什么,sbrk 只是修改程序中断的值,而不是 mmap 比这更复杂,为什么要用它来做所有事情?
    • 出于多种原因:通过sbrk()访问的内存量可能受到系统的限制,它必须形成一个连续的内存地址范围,该范围可以进一步受到堆栈和所在地址的限制。动态库被映射到。另一个原因是随机分配内存块,特别是在 64 位系统上,以使漏洞更难被利用。另一个原因是malloc() 可能使用多个竞技场,但对所有竞技场使用相同的代码,因此mmap
    猜你喜欢
    • 2011-03-05
    • 2019-11-23
    • 2015-09-11
    • 2022-01-16
    • 2012-10-01
    • 2020-05-14
    • 2015-12-23
    • 2017-01-28
    • 2019-12-10
    相关资源
    最近更新 更多