10内存

第十章 内存
 
1     程序的内存布局
Linux 的内存布局,按地址从高到低如下:
(1)     Kernel  0xffffffff―0xc00000000
(2)     Stack
(3)     Dynamic libraries  0xXXXXXXXX―0x400000000
(4)     Heap
(5)     Read/write section(.date .bss)
(6)     Readonly section(.init .rodate .text)  0xXXXXXXXX―0x08048000
(7)     Reserved  0x080480000―0x00000000
实际上在 linux 内核 2.6 版本后,共享库的装载地址已经挪到了 0xbfxxxxxx 附近。
 
2     栈与调用惯例
什么是栈
堆栈帧一般包含以下几个内容:
(1)       传入的参数
(2)       返回的地址
(3)       保存的寄存器(上下文)
(4)       临时变量
 
调用惯例 一般会包含一下几个方面的内容:
(1)       参数的传递方式和吮顺序
(2)       栈的维护方式(参数的弹出有调用者还是被调用者)
(3)       名字修饰策略
 
函数的返回值传递
 
MIPS 上关于栈的使用和维护的详细信息可以参考 see mips run 中的专门章节。
 
3     堆与内存管理
什么是堆
由于栈中的数据会在函数返回是释放,没有办法将数据传递到外面,而全局变量又不能动态的产生数据,所以堆应运而生。
虚拟地址空间是由操作系统管理的,用户的 malloc 怎么实现呢?比较好的方法是程序向操作系统申请一块适当大小的空间,然后由应用程序自己管理这块空间。
运行库作为应用程序和操作系统的中间商,管理堆空间。
 
Linux 进程堆管理
Linux 提供两种进程堆管理方法,一个是 brk() 系统调用,一个是 mmap() 系统调用。
brk() 的作用实际上就是设置进程数据段的结束地址,即它可以扩大或者缩小数据段。 Glibc 中的 sbrk() 就是对 brk() 的包装。
mmap() 的作用是像操作系统申请一段虚拟地址空间,而且这段虚拟地址空间可以映射到某个文件,也可以是匿名空间,由参数 flag 确定。
mmap(void *start, size_t length, int prot, int flag, int fd, off_t offset)
 
堆分配算法
(1)       空闲链表
(2)       位图
(3)       对想池
问题来了:堆其实只是进程向操作系统申请的一块地址空间,对于申请的堆和释放的堆,由谁来管理?操作系统?运行库?即对堆的数据结构描述由谁来管理?
实际上,操作系统或者运行库只是在虚拟地址空间上做一些增减,再设置一些读写权限。

你可能感兴趣的:(职场,内存,休闲,程序员的自我修养,链接装载和库)