Linux内存管理学习笔记--物理内存分配

简介:

每次深入了解一个技术问题,随着挖据的深入,都发现其背后总非常深的背景知识,甚至需要深入到很多底层系统,这个过程有时会让自己迷失,会让自己忘了当初的目的。

前篇中介绍系统启动时内存的使用情况,本篇将介绍简要Linux如何接管主机的物理内存、组织内存,最后会较为详细的介绍Linux分配内存的一段代码。

前面说了,Linux MM系统细节非常多,自己在探究的时候,也是尝试尽量抓住主线,这里也只能抽取了一些“主线剧情”介绍,其中还可以扩展出很多细节,看客感兴趣可以自己深究,后续如果兴趣还在,我也还会继续写出来。内核版本如果没有特别说明,就是使用2.6.33版本。

1. 物理内存组织

先声明一下,这里说的Linux都是运行Intel X86架构的。从80386开始,为了更好支持内存管理、虚拟内存技术,x86架构开始支持处理器的分页模式(分页是基于分段)。系统将内存分为一个个固定大小的块,称作“page frames”,x86架构每一个“page frames”大小为4096字节。Linux中使用struct page结构来描述一个“page frames”【链接中给出了2.6.18内核下的Page结构】,一个Page结构对应了一个物理内存页。

在Linux中,所有的struct page对象都放在一个数组mem_map,mem_map每一个元素对应一个Page。

2. NUMA下的内存结构

在NUMA架构下,系统根据CPU的物理颗数,将内存分成对应的Node。例如,两颗物理CPU,16GB内存的硬件:系统则将内存分成两个8GB,分别分配给两颗CPU:

my111.cm3:/root>#numactl --hardware
available: 2 nodes (0-1)
node 0 size: 8065 MB
node 1 size: 8080 MB

每一个Node,系统又将其分为多个Zone,64位x86架构下(参考:8.1.5),分为两个ZONE_DMA(低16MB,)、ZONE_NORMAL(其余内存)。所以NUMA架构下的内存分配,也就是在各个zone分配内存。

3. 内存分配函数栈

从底层系统的角度,内存分配有如下函数(这里介绍的底层函数,和上层函数的关系,以后再介绍):

这里来调查一下函数alloc_pages都做了些什么,都调用了哪些函数:

free_area是一个底层保存空闲内存页的数组,有着特殊的结构,它也是内存分配Buddy system的核心变量。

4. get_page_from_freelist和zone_reclaim_mode

上面函数get_page_from_freelist【mm/page_alloc.c】通过遍历系统中各个zone,来寻找可用内存,根据Linux系统中zone_reclaim_mode的设置不同,遍历时的行为略有不同。zone_reclaim_mode是Linux中的一个可配置参数,为了解该参数如何影响内存分配,那就打开get_page_from_freelist的代码,仔细看看遍历各个zone的流程:

上面看到,zone_reclaim_mode非零时,如果某个zone内存不够,则会尝试出发一次内存回收工作(zone_reclaim),等于零时,则直接尝试写一个zone。

上面是2.6.33内核的代码流程图,2.6.18(RHEL5.4的内核)中则因为没有zcl相对简单一些:

流程图中可以看到,zone_reclaim_mode非零时,get_page_from_freelist【mm/page_alloc.c】函数中会调用zone_watermark_ok扫描free_area,如果当面有没有足够的可用内存,就会调用zone_reclaim【mm/vmscan.c】函数回收内存,zone_reclaim实际调用zone_reclaim【mm/vmscan.】收回内存。

最后

每次深入了解一个技术问题,随着挖据的深入,都发现其背后总非常深的背景知识,甚至需要深入到很多底层系统,这个过程有时会让自己迷失,会让自己忘了当初的目的。如果是Linux方面的技术问题,一般最后会收缩到“体系结构”、“Linux原理”和“算法”,这恰恰对应了计算机系考研时候的三门课程:体系结构、操作系统、和数据结构

目录
相关文章
|
4月前
|
Linux API
Linux内核中的两种ID分配方式
Linux内核中的两种ID分配方式
|
5月前
|
负载均衡 监控 前端开发
在Linux中,如何配置负载均衡器以分配网络流量?
在Linux中,如何配置负载均衡器以分配网络流量?
|
5月前
|
负载均衡 算法 Linux
在Linux中,如何配置负载均衡器以分配网络流量?
在Linux中,如何配置负载均衡器以分配网络流量?
|
5月前
|
存储 程序员 编译器
c++学习笔记08 内存分区、new和delete的用法
C++内存管理的学习笔记08,介绍了内存分区的概念,包括代码区、全局区、堆区和栈区,以及如何在堆区使用`new`和`delete`进行内存分配和释放。
56 0
|
7月前
|
存储 编译器 C语言
【C++】学习笔记——内存管理
【C++】学习笔记——内存管理
60 15
|
6月前
|
缓存 监控 关系型数据库
深入理解Linux操作系统的内存管理机制
【7月更文挑战第11天】在数字时代的浪潮中,Linux操作系统凭借其强大的功能和灵活性,成为了服务器、云计算以及嵌入式系统等领域的首选平台。内存管理作为操作系统的核心组成部分,对于系统的性能和稳定性有着至关重要的影响。本文将深入探讨Linux内存管理的基本原理、关键技术以及性能优化策略,旨在为读者提供一个全面而深入的理解视角,帮助开发者和系统管理员更好地优化和管理Linux系统。
|
6月前
|
存储 Java
深入理解Java中的堆内存与栈内存分配
深入理解Java中的堆内存与栈内存分配
|
7月前
|
存储 C++
C primer plus 学习笔记 第12章 存储类别、链接和内存管理
C primer plus 学习笔记 第12章 存储类别、链接和内存管理
|
8月前
|
Ubuntu 网络协议 Linux
|
7月前
|
缓存 Linux Shell
Linux 内存管理与 Swap 空间扩展实践
该文介绍了Linux系统中`free`命令的使用,解析了其输出信息,包括物理内存(总内存、已用、空闲、缓存)和交换空间(总大小、使用和空闲)。Linux优先使用物理内存作缓存,当内存紧张时使用Swap空间。文章还提供了扩展Swap空间的步骤,并强调适度Swap使用对性能的影响,建议合理平衡物理内存和Swap的比例。

热门文章

最新文章