True you can use 3GB, but different parts of the 3GB are used
for different purposes. The simple explanation are, that there
are three different 1GB ranges for brk, mmap, and stack. However
mmap allocate bottom-up and stack allocate top-down, so what is
not used for stack can be used for mmap. So you can allocate
almost 2GB with mmap.
Actually brk cannot use all of the first 1GB, because usually
the executable is mapped aproximately 128.3MB into this area, and
brk starts above the executable. That means there is about 895MB
available for brk, after that you are bound to hit the first
mmap allocation.
>
> This application can't create any more threads. pthread_create returns
> EAGAIN. What could be the reason for that?
Each thread needs a stack which must be allocated from the shared
address space. If the thread library fails to allocate stack space,
it cannot create the thread. I guess it use mmap to allocate stack
space, so if the mmap area is full, no more threads can be created.
I think recent malloc versions can allocate from the brk area as
well as the mmap area. That would explain why you could still
allocate memory after the first 2GB have been used, but cannot
create any more threads. Of course it is also possible that your
address space have become too fragmented.
A look in /proc/%d/maps should explain what is happening.
There exist different patches for moving the split between brk
and mmap areas.
http://www.daimi.au.dk/~kasperd/comp.os.linux.development.faq.html#TASK_UNMAPPED_BASE
--
Kasper Dupont
Before execution, use "ldd main_app" to see where libraries go.
During execution, use "cat /proc/<pid>/maps" (or read /proc/self/maps)
to see which page frames are in use and which are available.
Also, the function values brk(0) and sbrk(0), and the symbols
_end _edata __bss_start, have relevant values.
See http://www.BitWagon.com/tub.html for a hack to control mmap(0,
...) on x86.
--