Reputation: 619
I always think stack locates at higher address than heap like the picture2. But I found that sometimes the heap address is higher when I test it using cpp(picture1). I know that the virtual memory is used but I also want to know why the virtual address of stack and heap dont follow the picture2? Thank you very much!
Upvotes: 3
Views: 3861
Reputation: 1
In practice, the heap data is not necessarily contiguous on recent Linux systems (and probably on most other desktop or server OSes). The virtual address space (VAS) wikipage has also a simplified figure.
On Linux systems, you can experiment with proc(5). Try cat /proc/self/maps
which shows on the terminal the virtual address space of the (current) cat
process. Try also cat /proc/$$/maps
(to get the VAS of your current shell) and (as root) cat /proc/$(pidof Xorg)/maps
(to get the VAS of your Xorg server). And try other cat /proc/
some-pid/maps
for various pids of various processes.
One of the explanation is that sometimes, malloc
will call mmap(2) and not only sbrk(2). In particular, malloc
of a large memory chunk will use mmap
(I think the "threshold" for using mmap
could be a malloc
of several megabytes). And libraries and application programs can use mmap
to access some file.
And mmap
is using ASLR so obviously won't give contiguous memory segments. Of course, an application (or the implementation of free
) could sometimes use munmap
to release memory. And dynamic linking (see ld-linux(8) & dlopen(3) ...) also use mmap
and munmap
.
So the virtual address space can be (and often is) made of many discontinuous memory segments (sometimes thousands of them).
BTW, multi-threading also wants several memory segments. Generally each thread has its own mmap
-ed stack space.
For example, I have some mate-terminal
terminal emulator running as process of pid 2594. Its process has 568 memory segments (i.e. lines in /proc/2594/maps
). I won't spoil this answer by showing all of them. And the firefox
browser process I am typing this answer in has 1229 lines in /proc/1604/maps
, here are some of them:
27423e6e0000-27423e720000 r-xp 00000000 00:00 0
27423e720000-27423e730000 r-xp 00000000 00:00 0
27423e730000-27423e760000 r-xp 00000000 00:00 0
27423e760000-27423e780000 r-xp 00000000 00:00 0
27423e780000-27423e7c0000 r-xp 00000000 00:00 0
27423e7c0000-27423e7d0000 r-xp 00000000 00:00 0
27423e7d0000-27423e7e0000 ---p 00000000 00:00 0
27423e7e0000-27423e7f0000 r-xp 00000000 00:00 0
7efed334d000-7efed3357000 r--p 00172000 08:01 11275829 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.23
7efed3357000-7efed3359000 rw-p 0017c000 08:01 11275829 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.23
7efed3359000-7efed335c000 rw-p 00000000 00:00 0
7efed335c000-7efed335f000 r-xp 00000000 08:01 1704007 /lib/x86_64-linux-gnu/libdl-2.24.so
7efed335f000-7efed355e000 ---p 00003000 08:01 1704007 /lib/x86_64-linux-gnu/libdl-2.24.so
7efed355e000-7efed355f000 r--p 00002000 08:01 1704007 /lib/x86_64-linux-gnu/libdl-2.24.so
So your picture is a gross simplification. I'm pretty sure that the fragmentation of the VAS also happens on other operating systems, notably for monster processes like e.g. your web browser.
Upvotes: 1
Reputation: 21627
Your diagram is just conceptual. It does not reflect the complexities of linking, dynamic loading, relocation, and run time memory allocation.
Upvotes: 1