我已经彻底阅读了关于sbrk()的linux手册:
sbrk()更改程序中断的位置,该位置定义结束 进程的数据段(即,程序中断是第一个) 未初始化数据段结束后的位置。)
问题是: 当我调用sbrk(1)时,为什么说我增加了堆的大小?正如手册所说,我正在改变“数据段& bss”的结束位置。那么,数据段的大小应该增加多少呢? bss,对吧?
答案 0 :(得分:3)
数据和bss段是固定大小。因此,在这些细分结束后分配给流程的空间不属于这些细分市场;它只是与它们相邻。该空间称为堆空间,用于动态内存分配。
如果您想将其视为'扩展数据/ bss细分市场,那也很好。它不会对程序的行为,或者分配的空间或任何东西产生任何影响。
Mac OS X上的手册页表明你真的不应该使用它们:
brk和sbrk函数是虚拟内存管理出现前几天遗留下来的历史好奇心。
brk()
函数设置进程的中断或最低地址' s数据段(未初始化的数据)到addr
(紧接在bss之上)。数据寻址在addr
和到堆栈段的最低堆栈指针之间受到限制。内存由页面大小的brk
分配;如果addr
不能被系统页面大小整除,则会增加到下一页边界。
sbrk(0)
可以可靠地返回程序中断的当前值(另请参阅 end(3))。 getrlimit(2)系统调用可用于确定数据段的最大允许大小;我们无法将中断设置为超出rlim_max
调用返回的getrlimit
值,例如etext + rlp->rlim_max
(有关etext
的定义,请参阅 end(3)。
令人感到有点恼火的是,我找不到 end(3)的手册页,尽管有关于它的指示。即使sbrk()
的这个(略显陈旧的)手册页也没有链接。
答案 1 :(得分:2)
请注意,今天很少使用sbrk(2)。大多数malloc
实现使用mmap(2) - 至少用于大型分配 - 来获取内存段(以及munmap
来释放它)。通常情况下,free
只是标记一个内存区域可以被某个未来malloc
重用(并且不会向Linux kernel释放任何内存)。
(实际上,现代linux进程的堆由几个段组成,因此比你的图片更精细;多线程进程每个{{3 }})功能
使用thread,尤其是/proc/self/maps
和/proc/$pid/maps
,了解某些proc(5)的virtual address space。首先尝试理解cat /proc/self/maps
(显示cat
命令的地址空间)和cat /proc/$$/maps
(显示shell的地址空间)的输出。另请尝试查看您的网络浏览器的maps
伪文件(例如cat /proc/$(pidof firefox)/maps
或cat /proc/$(pidof iceweasel)/maps
等...);我有超过一千行(所以过程段)。
使用process了解给定命令或进程完成的strace(1)。
利用Linux上的大多数(可能所有)system calls实现都是C standard library,因此您可以研究它们的源代码。 free software的源代码非常容易阅读。
另请阅读musl-libc,ELF,ASLR& dynamic linking,然后ld-linux(8)预订Advanced Linux Programming