• 转 [干货学习]好图 Linux内存管理学习笔记


    [干货学习]好图  Linux内存管理学习笔记

    作者一个故事@MySQL DBA

     


    1. 笔记导语

    Linux MM是一个比较猥琐的体系,虽然理论不太多,但是细节非常多。要从底层物理内存管理到上层虚拟内存管理整个关节打通,一方面需要较多底层架构知识、还需要很深的Linux知识。既然是学习笔记,先说一下我的学习资料:

    1.Linux Memory Management David A Rusling 这本书很老了,当时的Kernel还是2.0.33版本的;这本书的优点在于抽象得很到位,把Linux_MM的基本模块、思想都通俗易懂的介绍了一遍。这也是kernel-docs.txt中推荐的读物之一;

    2.《Understanding the Linux Kernel, 3rd Edition》中的第二、八、十七章这是基于2.6内核,非常有参考价值,介绍得非常细致,可以结合内核的源代码一起来看。

    3.Linux Source Code 只看了几个自己关心的函数,

    2. 基本框架

    clip_image001

    上面是一幅简图,后面会分别介绍,Kernel如何使用内存、Kernel如何管理分配内存、用户空间的内存管理。对于其中的一些细节则会单独介绍,例如大页内存,内存回收算等等。

    3. Linux启动与内存管理

    开机的第一个过程是BIOS自检,BIOS使用0x00000000到0x10000(1MB)内存,这1MB内存包括了自检程序、自检结果、还留一部分给显示设备使用;自检完成后,开始载入Linux内核,Linux从1MB开始使用物理内存,一般5MB就足够了,在内核的符号信息中可以看到,Linux内核从_text开始,_edata处结束

    clip_image002

    $more /boot/System.map-2.6.9-55.ELsmp|grep "\ _text$\|_etext$\| _edata$\| _end$"

    ffffffff80100000 A _text

    ffffffff80310399 A _etext

    ffffffff80456aa8 A _edata

    4. 物理内存组织

    先声明一下,这里说的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。

    clip_image003

    5. 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分配内存。

    6. 内存分配函数栈

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

    clip_image004

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

    clip_image005

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

    7. 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的流程:

    clip_image006

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

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

    clip_image007

    流程图中可以看到,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原理”和“算法”,这恰恰对应了计算机系考研时候的三门课程:体系结构、操作系统、和数据结构.

     

    源文档 <http://www.linkwan.com/gb/tech/htm/1581.htm>

  • 相关阅读:
    javascript变量
    javascript数据类型
    javascript基本语法
    javascript用法
    javascript简介
    js 随机生成颜色值
    JS 判断传入的变量类型是否是Array
    swiper2 swiper-slide 之间的间距调整
    IE9以及以下不支持jquery ajax跨域问题
    HBuilder只提示html 不提示js
  • 原文地址:https://www.cnblogs.com/titer1/p/2431590.html
Copyright © 2020-2023  润新知