本篇主要以问答的方式来探索Linux内存系统的分配策略
Linux 过程的内存散布长什么样?文章源自微观生活(93wg.com)微观生活-https://93wg.com/2937.html
在 Linux 操作系统中,虚拟地址空间的内部又被分为内核空间以及用户空间两部份,不同位数的系统,地址空间的规模也不同。比如最多见的 32 位以及 64 位系统,如下所示:文章源自微观生活(93wg.com)微观生活-https://93wg.com/2937.html
通过这里可以看出:文章源自微观生活(93wg.com)微观生活-https://93wg.com/2937.html
- 32 位系统的内核空间占用 1G,位于最高处,剩下的 3G 是用户空间;
- 64 位系统的内核空间以及用户空间都是 128T,分别盘踞整个内存空间的最高以及最低处,剩下的中间部份是不决义的。
再来讲说,内核空间与用户空间的区分:文章源自微观生活(93wg.com)微观生活-https://93wg.com/2937.html
- 过程在用户态时,只能走访用户空间内存;
- 只有进入内核态后,才可以走访内核空间的内存;
尽管每一个过程都各自有独立的虚拟内存,然而每一个虚拟内存中的内核地址,其实关联的都是相同的物理内存。这样,过程切换到内核态后,就能够很利便地走访内核空间内存。文章源自微观生活(93wg.com)微观生活-https://93wg.com/2937.html
接下来,进一步了解虚拟空间的划分情况,用户空间以及内核空间划分的方式是不同的,内核空间的散布情况就不多说了。文章源自微观生活(93wg.com)微观生活-https://93wg.com/2937.html
咱们看看用户空间散布的情况,以 32 位系统为例,我画了一张图来表示它们的关系:文章源自微观生活(93wg.com)微观生活-https://93wg.com/2937.html
通过这张图你可以看到,用户空间内存从低到高分别是 6 种不同的内存段:文章源自微观生活(93wg.com)微观生活-https://93wg.com/2937.html
- 程叙文件段,包含二进制可执行代码;
- 已初始化数据段,包含静态常量;
- 未初始化数据段,包含未初始化的静态变量;
- 堆段,包含动态分配的内存,从低地址开始向上增长;
- 文件映照段,包含动态库、同享内存等,从低地址开始向上增长(跟硬件以及内核版本有关 );
- 栈段,包含局部变量以及函数调用的上下文等。栈的大小是固定的,通常为 8 MB。固然系统也提供了参数,以便咱们自定义大小;
在这 6 个内存段中,堆以及文件映照段的内存是动态分配的。比如说,使用 C 标准库的 malloc 或者 妹妹ap ,就能够分别在堆以及文件映照段动态分配内存。文章源自微观生活(93wg.com)微观生活-https://93wg.com/2937.html
malloc 是怎么分配内存的?文章源自微观生活(93wg.com)微观生活-https://93wg.com/2937.html
实际上,malloc 其实不是系统调用,而是 C 库里的函数,用于动态分配内存。
malloc 申请内存的时候,会有两种方式向操作系统申请堆内存。
- 方式一:通过 brk 系统调用从堆分配内存
- 方式二:通过 妹妹ap 系统调用在文件映照区域分配内存;
方式一实现的方式很简单,就是通过 brk 函数将「堆顶」指针向高地址挪动,取得新的内存空间。如下图:
方式二通过 妹妹ap 系统调用中「私有匿名映照」的方式,在文件映照区别配一块内存,也就是从文件映照区“偷”了一块内存。如下图:
什么场景下 malloc 会通过 brk 分配内存?又是什么场景下通过 妹妹ap 分配内存?
malloc 源码里默许定义了一个阈值:
- 以上就是微观生活(93wg.com)关于“一文读懂Linux内存分配策略”的详细内容,希望对大家有所帮助!
评论