关于 sbrk() 和 malloc()

About sbrk() and malloc()

我已经彻底阅读了关于 sbrk() 的 linux 手册:

sbrk() changes the location of the program break, which defines the end of the process's data segment (i.e., the program break is the first location after the end of the uninitialized data segment).

而且我确实知道用户 space 的内存组织如下所示:

问题是: 当我调用 sbrk(1) 时,为什么它说我正在增加堆的大小?如手册所述,我正在更改 "data segment & bss" 的结束位置。那么,data segment & bss的size应该增加多少吧?

data 和 bss 段是固定大小的。因此,在这些段结束后分配给进程的 space 不是这些段的一部分;它只是与他们相邻。 space 称为堆 space 并用于动态内存分配。

如果你想把它当成'extending the data/bss segment',那也可以。它不会对程序的行为、分配的 space 或任何东西产生任何影响。

Mac OS X 上的手册页表明您真的不应该经常使用它们:

The brk and sbrk functions are historical curiosities left over from earlier days before the advent of virtual memory management. The brk() function sets the break or lowest address of a process's data segment (uninitialized data) to addr (immediately above bss). Data addressing is restricted between addr and the lowest stack pointer to the stack segment. Memory is allocated by brk in page size pieces; if addr is not evenly divisible by the system page size, it is increased to the next page boundary.

The current value of the program break is reliably returned by sbrk(0) (see also end(3)). The getrlimit(2) system call may be used to determine the maximum permissible size of the data segment; it will not be possible to set the break beyond the rlim_max value returned from a call to getrlimit, e.g. etext + rlp->rlim_max (see end(3) for the definition of etext).

有点恼火的是我找不到 end(3) 的手册页,尽管可以查看它。即使 sbrk() 的这个(有点旧)手册页也没有 link。

注意今天 sbrk(2) is rarely used. Most malloc implementations are using mmap(2) -at least for large allocations- to acquire a memory segment (and munmap to release it). Quite often, free simply marks a memory zone to be reusable by some future malloc (and does not release any memory to the Linux kernel).

(实际上,现代 linux 进程的堆由 多个 段组成,因此比您的图片更微妙;和多线程进程每个 thread)

有一个堆栈

使用proc(5), notably /proc/self/maps and /proc/$pid/maps, to understand the virtual address space of some process。首先尝试理解 cat /proc/self/maps(显示 cat 命令的地址 space)和 cat /proc/$$/maps(显示 space 命令的地址 space)的输出46=]).还请尝试查看适用于您的 Web 浏览器的 maps 伪文件(例如 cat /proc/$(pidof firefox)/mapscat /proc/$(pidof iceweasel)/maps 等...);我有超过一千行(所以过程段)在里面。

使用 strace(1) to understand the system calls 由给定的命令或进程完成。

利用 Linux 上的大部分(可能是全部)C standard library implementations are free software, so you can study their source code. The source code of musl-libc 很容易阅读。

另请参阅 ELF, ASLR, dynamic linking & ld-linux(8), and the Advanced Linux Programming book then syscalls(2)