程序员自我修养笔记:第十章

第十章 内存
1.调用惯例
一个调用惯例,一般会规定如下几方面的内容:
函数参数的传递顺序和方式:
参数的压栈顺序,有些惯例还允许使用寄存器传递参数。
站的维护方式:
参数的弹出工作是由函数的调用方还是函数本身来完成
名字修饰策略
函数返回值传递

2.堆
程序向操作系统申请一块适当大小的堆空间,然后由程序自己管理这块空间。这个程序往往是程序的运行库。
3.Linux下的对空间分配方式有两个系统调用,一个是brk(),另外一个是mmap()。
brk()就是设置进行数据段(bss+数据段)的结束地址,将数据段的结束地址向高地址移动,那么扩大的部分空间就是堆空间。glibc还有一个函数sbrk(),与brk类似,只是sbrk()以一个增量(可正可负),返回值是增量后的数据段结束地址,实际上是对brk()的包装。
mmap()类似Windows下的VirtualAlloc(),他向操作系统申请一段虚拟地址空间,可以将这段空间映射到某个文件,当他不映射到某个文件时,我们称之为匿名名空间。
void* mmap(
void* start,
size_t length,
int prot,
int flags,
int fd,
off_t offset);

glibc对于用户的空间请求有两种做法:对于小于128 KB的请求来说,他会在现有对空间内按照堆算法为他分配空间并返回;对于大于128 KB的请求来说,他会使用mmap为他分配一块匿名空间,然后在这个匿名空间中为用户分配空间。
堆空间的最大申请大小,取决于许多因素。比如内核版本不一样,还有系统资源限制,物理内存和交换空间的总和。
WINDOWS下WINDOWS的进程将地址空间分配给了各种EXE、DLL文件、堆、栈。且因为WINDOWS的运行库的原因,一个进程有多个线程,有多个栈。分配完后Windows的进程地址空间已经是支离破碎了,当程序向系统申请对于空间时之后,从剩下的这些没有被占用的地址分配。VirtualAlloc()申请空间时要求空间大小必须为页的整数倍。
WINDOWS下堆分配的算法实现位于堆管理器,推管理器提供了一套与堆相关的API用来创建分配、释放和销毁堆空间:
HeapCreate
HeapAlloc
HeapFree
HeapDestroy

3.堆分配算法
空闲链表:
在堆的每一个空闲空间的开头或结尾,有一个头头结构里记录了上一个或下一个空闲会的地址。
缺点是一旦电表被破坏或者记录长度的那四个字节被破坏,整个堆无法正常工作。
位图:
将整个堆划分为大量的会,每个块的大小相同,当用户请求内存时,总是分配整数个快给用户,第一个块为头,其余块为主体,因此,仅需要使用一个整数数组来记录会的使用情况。
好处是速度快,稳定性好快,不需要额外的信息易于管理。坏处是分配内存的时候容易产生碎片,且如果堆很大或者设定的一个会很小,那么,威图将很大,可能失去cache命中率高的优势。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值