小白垃圾笔记,不建议阅读。
目录
1.什么是堆?
2.堆从哪里来?
3.堆管理器是什么
4.堆申请的实现方式
1.brk:brk仅仅主线程申请小空间的时候用,子线程不可调用brk。
2.mmap:主线程申请大的内存的时候和子线程申请内存的时候。
3.堆的位置
4.决定因素小总结:
5.调用过程的层次关系:
看的视频是这个:
0009.哔哩哔哩-【个人向】CTF pwn 入门-P9[高清版]_哔哩哔哩_bilibili
堆部分大概从2:38:00开始;
1.什么是堆?
虚拟内存中一块连续的线性空间。用户空间随取随用的一段空间。
动态申请。
下图中绿色的部分。(heap)
2.堆从哪里来?
堆是由堆管理器:位于动态链接库。上图中堆栈之间的部分吧。
3.堆管理器是什么
堆管理器相当于批发商。介于操作系统和用户之间。面向于操作系统和用户。
面向用户:响应用户的申请请求。
面向操作系统:向操作系统申请实际的物理内存。并且把实际的物理内存自己存储起来。
再把自己存储的内存分发给用户。
堆管理器有各种各样的实现:
不同的操作系统不同的实现。
linux使用glibc中的堆管理器。
dlmallo——General purpose allocator
ptmalloc2——glibc(********重点********)
jemalloc——FreeBSD and Firefox
tcmalloc——Google
libumem——Solaris
堆管理器是用来向操作系统申请内存,之后在用户态把这些内存管理起来的一个用户态代码。
堆管理器是很长的一段代码。
堆管理器并不存在操作系统(Kernel)中,它存在于shared libraries(libc)中。
它的作用是用来管理下边的heap的内存。
那么用户态的代码是如和获取真正物理内存的?
系统调用
堆管理器封装了一些系统调用。通过系统调用向操作系统申请物理内存。申请的物理内存他自己先管理起来,再向用户提供一个向他申请内存的接口。
4.堆申请的实现方式
堆管理器是如何是实现申请操作系统所管理的物理内存的呢?
有两个申请内存的系统调用:
1.brk:brk仅仅主线程申请小空间的时候用,子线程不可调用brk。
brk(break):bss数据段实际是data的一部分,brk位于数据段的末尾。
brk就是从标记末尾的地方继续拓展,其实拓展的地方就是堆了。每调用一次brk data上边的区域就会被扩展大一点。
那这里的图明明是虚拟空间,刚刚不是说物理空间吗?
这就和系统的分页机制有关了。(我也不知道啥是分页机制。)
视频中这样说:
虚拟内存申清的的空间直接是从操作系统映射过来的。每一个页(4kb)都可以在操作系统找到对应的位置。
2.mmap:主线程申请大的内存的时候和子线程申请内存的时候。
mmap:memory map(内存映射)
什么是映射:对于动态链接段memory
实际的物理内存映射到虚拟内存中
每有一次新的申请都会在物理内存中申请一段物理空
空间然后映射(map)到mmap段。
3.堆的位置
所以:堆可以有两个位置
1.紧贴在data上方,向上增长
2.向物理内存要一大块空间映射到mmap的某个位置
4.决定因素小总结:
那么获取堆空间的两种方式是由什么决定的呢?
两个要素吧:
1:主线程都可以 过大用mmap,小用brk
2.子线程仅mmap
5.调用过程的层次关系:
下边是调用层次吧:
malloc:向堆管理器申请内存,如果没有就向下(下一层)执行。
free:向堆管理器归还内存。