一、x86 Linux 32位系统虚拟地址空间布局:
这里的段基址从0开始,可以访问管理的内存是4G;如果是段基址是从2G开始的,那么内存可以达到6G.
Linux进程使用内存的几种类型:
其中:
系统调用一般通过触发int 80中断陷入内核,一些比较新的芯片通过syscall指令来陷入内核。
Memory Mapping Segment:
内存映射段,用来映射文件,对应mmap()系统调用。
二、动态内存管理基础:
在Bss和Heap之间有一段Random brk内存,保证堆内存的起始地址是随机的,为了程序的安全,防止被攻击,因为数据和指令内存一般容易计算,如果紧接着就是堆的话,就很不安全。
动态的申请内存:
由于brk()扩展内存是线性的,他是由指针向上偏移获取内存,释放时需要向下挪动,
但是,如果要释放的内存上面的内存还没有使用完毕,就不能挪动释放
当我们用户申请内存<128kB 时,默认使用的是brk,当申请的内存大于128时,默认将使用mmap(), 由常量M_MMAP_THRESHOLD=128k 规定限制.
由于是直接从mmaping区域获取一整块内存,不是线性的,释放的时候比较容易
直接释放,与线性挪动brk指针释放而区别。
注意:
我们平时开发使用的malloc和new,一个是glibc的库函数,一个运算符重载,而malloc使用brk和mmap来获取内存;
我们通过malloc或者new申请内存时,申请的内存全是虚拟内存,直到使用的时候才会真正个分配物理内存,所以我们在程序调试时打印的地址也是虚拟地址,虚拟地址空间上的地址。
三、brk()和sbrk():
glibc库函数:
int brk(void *addr); addr=修改为program break地址; return=0、-1
void *sbrk(intptr_t increment); increment=program break增长的长度;return=旧program break的地址、失败返回-1。
sbrk()成功为什么返回旧地址:旧地址 + 申请内存的长度
库函数brk()和sbrk()调用的全是系统调用中的brk()。
系统调用brk:return=新program break地址、旧program break地址。
在Linux上,sbrk()被实现为使用brk()系统调用的库函数,并执行一些内部簿记,
也就是说sbrk()内部实现的时候会记录旧的地址,以便它可以返回旧的中断值。
注意:我们在编程中使用的绝大多数函数如fork()、brk()等都是库函数,不是系统调用,只不过我们使用的这些函数刚好和系统调用的名字相同。
四、mmap()管理内存:
大内存不适用brk(),是因为brk是线性挪动的,假设一开始申请一大块内存,
后面由申请一些小内存,如果不释放小内存,大内存就没法释放,这样系统资源压力会很大
发生缺页中断,cpu获取中断信息,去执行对应的中断处理程序,分配物理内存
如果内存不够,将一些进程信息移动到swap分区,然后再分配物理内存。
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
建议地址,最终不一定再这里开辟,最终由内核决定,只是建议使用这个地址,或者相邻地址
如果是空指针,完全由内核决定
r w x 等权限,权限是针对页说的,可读还是可写说的是这个页可读还是可写,这些
信息是记录在 页表 中的
五、ptmalloc简介:
glibc的内存管理就是ptmalloc,ptmalloc调用的brk()、mmap()系统调用。
glibc自建内存池对已获得系统内存进行管理(chunk):
需要双向查,数据的组织是有规律的,因为能判断出,查的时候是向前还是向后查
优化:
建树查询,这个树由一定的平衡性。时间复杂度比链表查询更快
蓝色部分是进程已经存在的,而需要brk管理的是白色区域的堆内存
5. 内存映射区管理:mmaped chunk(mmap调用获取的内存)。
下图为ptmalloc的内存管理组织方式:
fast:并不存在与上述空间,因为fast是空间换时间的概念。
六、三种内存管理方案的区别:
七、Linux伙伴系统:
八、计算机内存分配的发展历史:
九、内存管理的优化思路:
通用内存管理系统的缺点:
1.过于通用设计,考虑平均情况,中庸之道;
2.特殊内存使用方式无优化;
3.对系统资源使用过于保守。
特殊内存使用情景:
1.单一数据结构频繁申请释放(具有固定长度和组织形式);
2.提前预知内存使用规模;
3.类似std::move的情景,“迁移内存”而不是“申请-释放-申请”。
内存管理造轮子的意义:
1.砍掉无用的算法和优化;
2.针对系统的硬件场景优化(到指令级);
3.减少系统调用的次数。