问题描述
据Linux程序员手册:
According to Linux programmers manual:
BRK()和SBRK()更改程序符的位置,这
定义的过程的数据段的结束。
什么是数据段的意思是在这里?难道仅仅是数据段或数据,BSS和堆结合起来呢?
What does the data segment mean over here? Is it just the data segment or data, BSS, and heap combined?
据维基:
有时候数据,BSS和堆区域被统称为数据段。
我认为没有理由改变只是数据段的大小。如果是数据,BSS和堆集体的话很有道理的堆会得到更多的空间。
I see no reason for changing the size of just the data segment. If it is data, BSS and heap collectively then it makes sense as heap will get more space.
这让我想起我的第二个问题。在所有我迄今为止看过的文章,作者说,堆中向上生长和堆栈向下增长。但他们没有解释的是,当堆占全部堆和栈之间的空间会发生什么?
Which brings me to my second question. In all the articles I read so far, author says that heap grows upward and stack grows downward. But what they do not explain is that what happens when heap occupies all the space between heap and stack?
推荐答案
我看很多部分答案,但没有完整的答案。下面是再次张贴图片:
I see a lot of partial answers but no complete answer. Here's that picture you posted again:
在破发 - 就是在虚线 - 以 BRK
和 SBRK
操纵地址在堆顶部的。你读过的文档描述为数据段的结束,因为在传统的(pre-共享库,pre - MMAP
) Unix的数据段与堆连续的;节目开始前,内核将装载文本和数据块到RAM中起始地址为零(实际上略高于零地址,使NULL指针真的没有指向任何东西),并设置断点地址数据段的结束。第一次调用的malloc
然后将使用 SBRK
移动向上突破并创建堆的之间的数据段和新的,更高的断裂地址的顶部,如在图中示出,和随后使用的malloc
将用它来作堆更大作为必要的。
The "break"--the address manipulated by brk
and sbrk
--is the dotted line at the top of the heap. The documentation you've read describes this as the end of the "data segment" because in traditional (pre-shared-libraries, pre-mmap
) Unix the data segment was continuous with the heap; before program start, the kernel would load the "text" and "data" blocks into RAM starting at address zero (actually a little above address zero, so that the NULL pointer genuinely didn't point to anything) and set the break address to the end of the data segment. The first call to malloc
would then use sbrk
to move the break up and create the heap in between the top of the data segment and the new, higher break address, as shown in the diagram, and subsequent use of malloc
would use it to make the heap bigger as necessary.
与此同时,堆栈开始于内存的顶部,向下增长。堆栈并不需要明确的系统调用,使之做大;要么开始与分配给它尽可能多的RAM,因为它永远不会有(这是传统方法),或存在栈低于保留地址的区域,到时它注意到试图写有内核自动分配内存(这是现代的方法)。无论哪种方式,有可能会或可能不会在可用于堆栈地址空间的底部的后卫区域。如果这个区域存在(所有现代系统做到这一点),它是永久映射的;如果的或者的堆栈或堆试种到它,你就会得到一个分段错误。传统上,但是,内核并没有试图强制执行的边界;堆栈可以长成堆,或堆可以长成摞,无论哪种方式,他们会乱写了彼此的数据,程序就会崩溃。如果你是非常幸运的,将立即崩溃。
Meantime, the stack starts at the top of memory and grows down. The stack doesn't need explicit system calls to make it bigger; either it starts off with as much RAM allocated to it as it can ever have (this was the traditional approach) or there is a region of reserved addresses below the stack, to which the kernel automatically allocates RAM when it notices an attempt to write there (this is the modern approach). Either way, there may or may not be a "guard" region at the bottom of the address space that can be used for stack. If this region exists (all modern systems do this) it is permanently unmapped; if either the stack or the heap tries to grow into it, you get a segmentation fault. Traditionally, though, the kernel made no attempt to enforce a boundary; the stack could grow into the heap, or the heap could grow into the stack, and either way they would scribble over each other's data and the program would crash. If you were very lucky it would crash immediately.
我不知道在哪里这个图中的数512GB从何而来。它意味着一个64位的虚拟地址空间,这是与有有非常简单的存储器映射不一致。一个真正的64位地址空间看起来更像是这样的:
I'm not sure where the number 512GB in this diagram comes from. It implies a 64-bit virtual address space, which is inconsistent with the very simple memory map you have there. A real 64-bit address space looks more like this:
这是无法远程扩大规模,并且它不应该是作为PTED间$ P $任何给定的OS究竟是如何做的东西(后我画它,我发现,Linux的其实是把可执行文件更接近于解决零比我想象它做到了,在高得惊人地址共享库)。本图中的黑色区域是未映射 - 任何访问会立即段错误 - 他们的巨大的相对灰色地带。浅灰色的区域是程序及其共享库(可以有几十共享库);每个人都有一个的独立的文本和数据段(和BSS段,其中还包含全局数据,但被初始化为所有位为零,而不是占用空间在磁盘上的可执行文件或库)。堆不再是必然连续的可执行文件的数据段 - 我画了这样的说法,但它看起来像Linux的,至少,不做到这一点。堆栈不再盯住单一的虚拟地址空间的顶部,堆和栈之间的距离是如此之大,你不必担心它穿越
This is not remotely to scale, and it shouldn't be interpreted as exactly how any given OS does stuff (after I drew it I discovered that Linux actually puts the executable much closer to address zero than I thought it did, and the shared libraries at surprisingly high addresses). The black regions of this diagram are unmapped -- any access causes an immediate segfault -- and they are gigantic relative to the gray areas. The light-gray regions are the program and its shared libraries (there can be dozens of shared libraries); each has an independent text and data segment (and "bss" segment, which also contains global data but is initialized to all-bits-zero rather than taking up space in the executable or library on disk). The heap is no longer necessarily continous with the executable's data segment -- I drew it that way, but it looks like Linux, at least, doesn't do that. The stack is no longer pegged to the top of the virtual address space, and the distance between the heap and the stack is so enormous that you don't have to worry about crossing it.
突破仍是堆的上限。然而,我并没有显示的是,可能有几十显存独立分配了那里的黑的地方,用 MMAP
制成,而不是的BRK
。 (OS将尽量保持这些远离 BRK
区域,以便它们不会发生碰撞。)
The break is still the upper limit of the heap. However, what I didn't show is that there could be dozens of independent allocations of memory off there in the black somewhere, made with mmap
instead of brk
. (The OS will try to keep these far away from the brk
area so they don't collide.)
这篇关于是什么BRK()系统调用呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!