http://www.cnblogs.com/arnoldlu/p/8051674.html#memory_management_architecture

Linux的内存管理涉及到的内容非常庞杂,而且与内核的方方面面耦合在一起,想要理解透彻非常困难。

在开始学习之前进行了一些准备工作《如何展开Linux Memory Management学习?》,

1. 参考资料

遂决定以如下资料作为参考,进行Linux内存管理的研究:

《奔跑吧 Linux内核》:以第2章为蓝本展开,这是目前能获取的紧跟当前内核发展(Linux 4.0),并且讲的比较全面的一本资料。

《Understanding the Linux Virtual Memory Manager》:简单说就是虽老但经典,基于(Linux 2.4/2.6)。作者是目前仍然活跃在Linux社区MM专家。

《wowotech Memory Management》:没有其他系列经典,也没有条理系列的介绍MM,但是仍然值得按考。

《tolimit Linux内存源码分析》:相对零散的介绍了内存相关分析文档

《Linux Kernel v4.0》:当然必不可少的,是源码了。

当逐渐深入看到MMU相关代码时,读一下ARM架构关于MMU的规格书有助于理解。

不然对于虚拟地址到物理地址的映射就会很虚无,这些资料包括《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》的《Virtual Memory System Architecture》,以及相关MMU TRM。

2. Linux Memory Management框架图

整个内存管理从宏观上可以分为三大部分:用户空间、内核空间和相关硬件

用户空间主要是libc对相关系统调用进行封装,对用户程序提供API,常用的有malloc、mmap、munmap、remap、madvise、mempolicy等等。

相关硬件包括MMU/TLB、L1/L2 Cache以及DDR RAM,具体到ARM架构需要对照MMU/L2 Cache以及RAM规格书。

内核空间就复杂多了,首先介绍初始化及初始化后的布局。

2.1 物理内存初始化从获取内存大小、初始化页表,再进行zone初始化,然后在zone中使用伙伴系统进行物理内存初始化

2.2 页表的映射过程讲述了ARM32和ARM64两种架构下的页表映射,如何从虚拟地址由MMU转化成物理页面地址的

2.3 内核内存的布局图在内存被初始化之后,内核的内存布局基本上就确定了,ARM32和ARM64下布局有很大区别。在malloc一节brk中介绍了用户空间的布局。

2.1~2.3是内存的一个静态状态,在有了这些基础之后,2.4~2.9按照从低层到上层的逐个介绍了。

2.4 分配物理页面介绍了基于伙伴系统的页分配和释放;

2.5 slab分配器基于伙伴系统,slab分配更小内存块;以及基于slab的kmalloc;

2.6 vmalloc和kmalloc区别在于v,即在VMALLOC区域分配;

2.7 VMA即Virtual Memory Area,是进程内存管理的核心;

2.8 malloc和2.9 mmap都基于VMA,malloc/free用于分配/释放一块内存;mmap/munmap用于匿名/文件映射到用户空间。以及mmap(补充)。

由于malloc/mmap分配内存并不是立即分配,只是在用到的时候才会触发2.10 缺页中断处理。

在缺页但页不足的情况下,就需要进行一些操作调整内存,这些操作的基础是2.11 page引用计数,还有页面的2.12 反向映射RMAP技术。

在内存不足情况下触发kswapd2.13 回收页面,其中匿名页面有着特殊的2.14 匿名页面生命周期。

在kswapd回收依然无法满足内存分配,就需要对内存进行2.16 内存规整,它依赖的技术是2.15 页面迁移。

由于内存中存在一些内容完全一样的页面,使用2.17 KSM技术进行合并,同时利用COW技术,在需要时重新分配。

还介绍了2.18 Dirty COW内存漏洞,然后对内存管理数据结构和API进行了总结2.19 总结内存管理数据结构和API。

最后2.20 最新更新和展望对新技术进行了介绍。

除了以上技术,还有如下内存技术:

swap计数把匿名页面写入SWAP分区从而释放出空闲页面
内存压缩技术zram(a compressed RAM based swap device)
zswap技术是zram和swap的一个综合,首先将待换出页面进行压缩,存储到系统RAM动态分配的内存池中;达到一定阈值后再写入实际交换设备。
在内存极端不足情况下使用21 OOM(Out-Of-Memory)来杀死不重要进程获取更多内存的技术
基于cgroup的Memory资源控制
解决多媒体对大量连续内存需求的CMA(Contiguous Memory Allocator)技术
slub分配器
memory hotplug内存热插拔支持动态更换内存物理设备

==============================================================================================================================

在对内存相关技术了解过后,就是如何运用的问题了?

一方面是对内存问题进行定位;另一方面是对内存行为施加影响,进行优化。

22 内存检测技术对Linux内存常见问题及其定位方法和工具(slub_debug/kmemleak/kasan)进行了讲解。

23 一个内存Oops解析以一个内存Oops为例,介绍了内存相关异常分析。

内存sysfs节点和工具介绍了linux内存管理相关sysfs节点,以及工具;借助这些可以对内存进行优化。

扩展阅读:

关于zram、zswap、zcache的区别与各自优缺点《zram vs zswap vs zcache Ultimate guide: when to use which one》


Linux内存管理框架图
3. 代码和测试环境搭建
3.1 QEMU

安装QEMU以及相关编译工具

sudo apt-get install qemu libncurses5-dev gcc-arm-linux-gnueabi build-essential

3.2 Busybox 1.24

下载Busybox 1.24代码:

git clone https://github.com/arnoldlu/busybox.git -b 1_24_stable

编译Busybox:

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
#make menuconfig #P684,进行配置
make -j4 install

配置initramfs:
复制代码

sudo cp -r running_kernel_initramfs/* _install/
sudo chmod +x _install/etc/init.d/rcS
cd _install
mkdir mnt
mkdir dev
cd dev
sudo mknod console c 5 1
sudo mknod null c 1 3

复制代码

3.3 Kernel 4.0

下载Linux Kernel 4.0代码:

git clone https://github.com/arnoldlu/linux.git -b running_kernel_4.0

编译Linux Kernel:

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
make vexpress_defconfig #P685进行配置
make bzImage -j4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
make dtbs

3.4 运行内核

#Run Kernel+Busybox in QEMU
qemu-system-arm -M vexpress-a9 -smp 4 -m 1024M -kernel arch/arm/boot/zImage -append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic

至此,已经有一个完整的环境,提供shell命令。

  1. 思考问答

    在系统启动时,ARM Linux内核如何知道系统中有多大的内存空间?
    在32bit Linux内核中,用户空间和内核空间的比例通常是3:1,可以修改成2:2吗?
    物理内存页面如何添加到伙伴系统中,是一页一页添加,还是以2的几次幂来加入呢?
    内核的一级页表存放在什么地方?二级页表又存放在什么地方?
    用户进程的一级页表存放在什么地方?二级页表呢?
    在ARM32系统中,页表是如何映射的?在ARM64系统中,页表又是如何映射的?
    请简述Linux内核在理想情况下页面分配器(page allocator)是如何分配出连续物理页面的。
    在页面分配器中,如何从分配掩码(gfp_mask)中确定可以从哪些zone中分配内存?
    页面分配器是按照什么方向来扫描zone的?
    为用户进程分配物理内存,分配掩码应该选用GFP_KERNEL,还是GFP_HIGHUSER_MOVABLE呢?
    slab分配器是如何分配和释放小块内存的?
    slab分配器中有一个着色的概念(cache color),着色有什么作用?
    slab分配其中的slab对象有没有根据Per-CPU做一些优化?
    slab增长并导致大量不用的空闲对象,该如何解决?
    请问kmalloc、vmalloc和malloc之间有什么区别以及实现上的差异?
    使用用户态的API函数malloc()分配内存时,会马上为其分配物理内存吗?
    假设不考虑libc的因素,malloc分配100Byte,那么实际上内核是为其分配100Byte吗?
    假设两个用户进程打印的malloc()分配的虚拟地址是一样的,那么在内核中这两块虚拟内存是否打架了呢?
    vm_normal_page()函数返回的是什么样页面的struct page数据结构?为什么内存管理代码中需要这个函数?
    请简述get_user_page()函数的作用和实现流程?
    请简述follow_page()函数的作用和实现流程?
    请简述私有映射和共享映射的区别。
    为什么第二次调用mmap时,Linux内核没有捕捉到地址重叠并返回失败呢?
    struct page数据结构中的_count和_mapcount有什么区别?
    匿名页面和page cache页面有什么区别?
    struct page数据结构中有一个锁,请问trylock_page()和lock_page()有什么区别?
    在Linux 2.4.x内核中,如何从一个page找到所有映射该页面的VMA?反响映射可以带来哪些便利?
    阅读Linux 4.0内核RMAP机制的代码,画出父子进程之间VMA、AVC、anon_vma和page等数据结构之间的关系图。
    在Linux 2.6.34中,RMAP机制采用了新的实现,在Linux 2.6.33和之前的版本中称为旧版本RMAP机制。那么在旧版本RMAP机制中,如果父进程有1000个子进程,每个子进程都有一个VMA,这个VMA里面有1000个匿名页面,当所有的子进程的VMA同时发生写复制时会是什么情况呢?
    当page加入lru链表中,被其他线程释放了这个page,那么lru链表如何知道这个page已经被释放了。
    kswapd内核线程何时会被唤醒?
    LRU链表如何知道page的活动频繁程度?
    kswapd按照什么原则来换出页面?
    kswapd按照什么方向来扫描zone?
    kswapd以什么标准来退出扫描LRU?
    手持设备例如Android系统,没有swap分区或者swap文件,kswapd会扫描匿名页面LRU吗?
    swappiness的含义是什么?kswapd如何计算匿名页面和page cache之间的扫描比重?
    当系统充斥着大量只访问一次的文件访问(use-one streaming IO)时,kswapd如何来规避这种风暴?
    在回收page cache时,对于dirty的page cache,kswapd会马上回写吗?
    内核有哪些页面会被kswapd写回交换分区?
    ARM32 Linux如何模拟这个Linux版本的L_PTE_YOUNG比特位呢?
    如何理解Refault Distance算法?
    请简述匿名页面的生命周期。在什么情况下会产生匿名页面?在什么条件下会释放匿名页面?
    KSM是基于什么原理来合并页面的?
    在KSM机制里,合并过程中把page设置成写保护的函数write_protect_page()有这样一个判断:。这个判断的依据是什么?
    如果多个VMA的虚拟页面同时映射了同一个匿名页面,那么此时page->index应该等于多少?
    为什么Dirty COW小程序可以修改一个只读文件的内容?
    在Dirty COW内存漏洞中,如果Diryt COW程序没有madviseThread线程,即只有procselfmemThread线程,能否修改foo文件的内容呢?
    假设在内核空间获取了某个文件对应的page cache页面的struct page数据结构,而对应的VMA属性是只读,那么内核空间是否可以成功修改该文件呢?
    如果用户进程使用只读属性(PROT_READ)来mmap映射一个文件到用户空间,然后使用memcpy来写这段内存空间,会是什么样的情况?
    请画出内存管理中常用的数据结构的关系图,如mm_struct、vma、vaddr、page、pfn、pte、zone、paddr和pg_data等,并思考如下转换关系。
    请画出在最糟糕的情况下分配若干个连续物理页面的流程图。
    在Android中新添加了LMK(Low Memory Killer),请描述LMK和OOM Killer之间的关系。
    请描述一致性DMA映射dma_alloc_coherent()函数在AEM中是如何管理cache一致性的?
    请描述流式DMA映射dma_map_single()函数在ARM中是如何管理cache一致性的?
    为什么在Linux 4.8内核中要把基于zone的LRU链表机制迁移到基于Node呢?

Linux内存管理专题相关推荐

  1. Linux内存管理 (2)页表的映射过程

    专题:Linux内存管理专题 关键词:swapper_pd_dir.ARM PGD/PTE.Linux PGD/PTE.pgd_offset_k. Linux下的页表映射分为两种,一是Linux自身的 ...

  2. Linux内存管理 (4)分配物理页面

    专题:Linux内存管理专题 关键词:分配掩码.伙伴系统.水位(watermark).空闲伙伴块合并. 我们知道Linux内存管理是以页为单位进行的,对内存的管理是通过伙伴系统进行. 从Linux内存 ...

  3. Linux内存page,【原创】(十四)Linux内存管理之page fault处理

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  4. linux内存管理子系统采用基于内存区域,Linux 内存管理之highmem简介

    一.Linux内核地址空间 一般来说Linux 内核按照 3:1 的比率来划分虚拟内存(X86等):3 GB 的虚拟内存用于用户空间,1GB 的内存用于内核空间.当然有些体系结构如MIPS使用2:2 ...

  5. Windows内存管理和linux内存管理

    windows内存管理 windows 内存管理方式主要分为:页式管理,段式管理,段页式管理. 页式管理的基本原理是将各进程的虚拟空间划分为若干个长度相等的页:页式管理把内存空间按照页的大小划分成片或 ...

  6. 万字长文,别再说你不懂Linux内存管理了(合辑),30 张图给你安排的明明白白...

    之前写了两篇详细分析 Linux 内存管理的文章,读者好评如潮.但由于是分开两篇来写,而这两篇内容其实是有很强关联的,有读者反馈没有看到另一篇读起来不够不连贯,为方便阅读这次特意把两篇整合在一起,看这 ...

  7. 别再说你不懂Linux内存管理了,10张图给你安排的明明白白!

    来自:后端技术学堂 过去的一周有点魔幻,有印象的有三个新闻:天猫总裁绯闻事件,蘑菇街裁员,不可能打工的周某也放出来了.三件事,两件和互联网行业相关,好像外面的世界很是精彩啊!吃瓜归吃瓜,学习还是不能落 ...

  8. Linux内存管理原理【转】

    转自:http://www.cnblogs.com/zhaoyl/p/3695517.html 本文以32位机器为准,串讲一些内存管理的知识点. 1. 虚拟地址.物理地址.逻辑地址.线性地址 虚拟地址 ...

  9. Linux内存管理【转】

    转自:http://www.cnblogs.com/wuchanming/p/4360264.html 转载:http://www.kerneltravel.net/journal/v/mem.htm ...

  10. Linux内存管理之高端内存映射

    一:引子 我们在前面分析过,在linux内存管理中,内核使用3G->4G的地址空间,总共1G的大小.而且有一部份用来做非连续空间的物理映射(vmalloc).除掉这部份空间之外,只留下896M大 ...

最新文章

  1. 提交表单自动刷新_Web自动化测试:元素的基础操作和浏览器基础操作
  2. (0098)iOS开发之应用间的分享系列(3)
  3. linux双机热备软件 mysql_linux mysql双机热备
  4. LeetCode 117. 填充每个节点的下一个右侧节点指针 II(递归循环)
  5. 为什么编程语言以及数据库要从1970年1月1日开始计算时
  6. YAM将于明日在DegenerativeFinance上发布uSTONKS
  7. 【报告分享】2021年中国人工智能产业研究报告:数字经济时代的产业升级探索.pdf(附下载链接)...
  8. [导入]关于:web.config 的配置说明
  9. kali系统的部分查看命令
  10. 四小龙变“四小虫”?AI独角兽们的AI+故事好不好讲?
  11. [编程题]雀魂启动! C++
  12. crc16的c语言函数 计算ccitt_求一个C语言实现的CRC16/CCITT-FALSE校验码函数
  13. 加密和解密的应用_万金油_新浪博客
  14. 安装python包的时候文件夹权限报错:InvalidArchiveError(“Error with archive D:\\anaconda\\pkgs\\cudnn-8.4.1.50-h)
  15. 计算机通信机房消防要求,信息机房对环境有什么要求
  16. DocArray 0.21.0版本发布!新增OpenSearch后端存储,支持Redis后端存储的多语言文本搜索!...
  17. 闲话复数(1) | 不现实的虚数 i 为什么虚?它长成什么样?
  18. 设计模式.外观模式Facade
  19. 机房动力环境监控系统
  20. 集成ci jenkins_使用jenkins fastlane第1 2部分将ci cd集成到多个环境中

热门文章

  1. 用双重for循环打印正三角形和倒三角形的思路
  2. (转)C# 温故而知新:Stream篇(五)
  3. STM32F103_study60_The punctual atoms(Input capture experimentInput)
  4. Python下通过PR曲线值计算AP
  5. c语言打鱼晒网问题报告书,C语言渔夫打鱼晒网问题.docx
  6. python数据分析与应用第四章实训答案_《python数据分析与应用》第四章:pandas统计分析基础...
  7. 前端车牌识别SDK算法提取
  8. linux查看硬盘插槽_SSD小讲堂丨自己动手丰衣足食 手把手教你安装M.2固态硬盘
  9. MSXML的不同版本使用
  10. pthread编译时报错的解决方法