Linux 性能优化实战
倪朋飞
资深 Linux 专家,Kubernetes 项目维护者
87256 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 65 讲
结束语 (1讲)
Linux 性能优化实战
15
15
1.0x
00:00/00:00
登录|注册

15 | 基础篇:Linux内存是怎么工作的?

思考
如何查看内存使用情况
内存分配与回收
虚拟内存空间分布
内存映射
Linux内存工作原理

该思维导图由 AI 生成,仅供参考

你好,我是倪朋飞。
前几节我们一起学习了 CPU 的性能原理和优化方法,接下来,我们将进入另一个板块——内存。
同 CPU 管理一样,内存管理也是操作系统最核心的功能之一。内存主要用来存储系统和应用程序的指令、数据、缓存等。
那么,Linux 到底是怎么管理内存的呢?今天,我就来带你一起来看看这个问题。

内存映射

说到内存,你能说出你现在用的这台计算机内存有多大吗?我估计你记得很清楚,因为这是我们购买时,首先考虑的一个重要参数,比方说,我的笔记本电脑内存就是 8GB 的 。
我们通常所说的内存容量,就像我刚刚提到的 8GB,其实指的是物理内存。物理内存也称为主存,大多数计算机用的主存都是动态随机访问内存(DRAM)。只有内核才可以直接访问物理内存。那么,进程要访问内存时,该怎么办呢?
Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。这样,进程就可以很方便地访问内存,更确切地说是访问虚拟内存。
虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同字长(也就是单个 CPU 指令可以处理数据的最大长度)的处理器,地址空间的范围也不同。比如最常见的 32 位和 64 位系统,我画了两张图来分别表示它们的虚拟地址空间,如下所示:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Linux内存管理是操作系统中的核心功能之一。Linux内核为每个进程提供独立的虚拟地址空间,方便进程访问内存。虚拟地址空间被分为内核空间和用户空间,进程在用户态只能访问用户空间内存,而进入内核态后才能访问内核空间内存。内存映射通过页表将虚拟内存地址映射到物理内存地址,而TLB缓存可以提高CPU的内存访问性能。Linux提供了多级页表和大页机制来管理内存页,以减少页表项数量和提高内存访问效率。虚拟内存空间包括只读段、数据段、堆、文件映射段和栈,其中堆和文件映射段的内存是动态分配的。总体而言,Linux内存管理涉及虚拟地址空间的管理、内存映射、页表机制和虚拟内存空间的分布。 内存分配与回收方面,Linux使用brk()和mmap()两种方式来分配内存,对小块内存使用brk(),对大块内存使用mmap()。了解这两种调用方式后,需要清楚一点,当这两种调用发生后,其实并没有真正分配内存,而是在首次访问时才分配。Linux使用伙伴系统来管理内存分配,以页为单位进行管理,并通过相邻页的合并减少内存碎片化。对于小内存,Linux通过slab分配器来管理内核中的小对象。 在了解内存的工作原理之后,可以通过free、top或ps等工具查看系统内存使用情况。free工具显示整个系统的内存使用情况,而top输出则包含了系统整体的内存使用情况以及各个进程的内存使用情况。通过这些工具,可以快速了解系统的内存使用情况。 此外,文章还介绍了Linux系统内存回收的方式,包括回收缓存、回收不常访问的内存和杀死进程等方式。同时还介绍了Swap交换和OOM(Out of Memory)机制,以及如何查看内存使用情况和调整进程的oom_score。 总的来说,本文详细介绍了Linux内存管理的原理、内存分配与回收、内存使用情况查看以及系统内存回收的方式,为读者提供了全面的Linux内存管理知识。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Linux 性能优化实战》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(146)

  • 最新
  • 精选
  • JohnT3e
    目前我配合使用《Operating System Concepts》这本书学习此专栏,也是一个不错的选择。此书中的第四部分“Memory Management”对今天这部分内容有较为详细的描述,感兴趣的同学可以去看一下。另外对于TOP命令中输出的内存情况解释,可以认真看一下man手册的内容。如果你动手能力比较强,可以看https://blog.holbertonschool.com/hack-the-virtual-memory-malloc-the-heap-the-program-break/这篇博客,手把手教你使用程序(C语言)来实际地去搞清楚虚拟内存分布。

    作者回复: 👍 谢谢分享,这篇博客很详细

    2018-12-24
    3
    188
  • 梦回汉唐
    1、调用c标准库的都是用户空间的调用,用户空间的内存分配都是基于buddy算法(伙伴算法),并不涉及slab 2、brk()方式之所以会产生内存碎片,是由于brk分配的内存是推_edata指针,从堆的低地址向高地址推进。这种情况下,如果高地址的内存不释放,低地址的内存是得不到释放的 3、mmap()方式分配的内存,是在堆与栈之间的空闲区域分配虚拟内存,直接拿到的是内存地址,可以直接操作内存的释放 上述的都是在用户空间发生的行为,只有在内核空间,内核调用kmalloc去分配内存的时候,才会涉及到slab

    作者回复: 👍

    2019-03-27
    6
    80
  • 我来也
    [D15打卡] linux的内存跟windows的很不一样。类linux的系统会尽量使用内存缓存东西,提供运行效率。所以linux/mac显示的free剩余内存通常很小,但实际上被缓存的cache可能很大,并不代表系统内存紧张! 曾经就闹过笑话,看见系统free值很低,怕程序因为oom被系统杀掉,还特意写个c程序去挤内存。程序不停的申请1MB内存然后memset,随机挑几个位置写,保证申请的都被加载到物理内存中。(跟文中描述的一致,只申请不使用不会加载到物理内存)然后挤的差不多了就把测试程序关掉。看上去free变大了很多很开心。现在想想,就是掩耳盗铃罢了。 以前物理机上还有swap交换分区,现在都是云服务器,基本没有了该分区。也不会遇到因为频繁使用交换分区导致性能下降的问题了。 我内存方面的问题遇到的都比较简单,基本上就是top/free看看系统和各程序的,找到有问题的程序,看看是否有内存泄露。平常不泄漏都是够用的。 redis对内存比较敏感,曾经就因为配置项是默认值,在内存用完后,所有的set操作都直接返回错误,导致线上系统故障。(redis在备份时会新开一个进程,实际使用内存量会翻番。)后来会定期检查redis 的info memory 看内存使用情况。 —————————— 期待的内存篇开始了,好开心!又可以跟着老师学新知识啦!

    作者回复: 👍 谢谢分享你的经历。缓存和swap后面都还会细讲

    2018-12-24
    7
    61
  • 老师您好,请问如果发生了OOM,系统会记录下是哪个(些)进程被杀掉吗?

    作者回复: 会的,比如 dmesg |grep -E ‘kill|oom|out of memory’

    2018-12-24
    2
    33
  • 划时代
    我的分析步骤:使用top和ps查询系统中大量占用内存的进程,使用cat /proc/[pid]/status和pmap -x pid查看某个进程使用内存的情况和动态变化。

    作者回复: 👍

    2018-12-24
    33
  • espzest
    用户空间malloc不会使用slab机制吧,slab是内核空间的,对不?

    作者回复: 嗯嗯,是的,谢谢指出。slab是内核空间的,只用来管理内核中的小块内存

    2018-12-24
    3
    32
  • 亮点
    倪老师,“Operating Systems Design and Implementation”里面说,大部分页式存储管理,页表是存储到内存里面的,为降低频繁访问内存计算物理地址,引入TLB用于缓存常用映射以提升性能。以现在流行的linux为例,本节课说页表存储在MMU是否还正确呢?

    作者回复: MMU全称就是内存管理单元,管理地址映射关系(也就是页表)。但MMU的性能跟CPU比还是不够快,所以又有了TLB。TLB实际上是MMU的一部分,把页表缓存起来以提升性能。

    2018-12-24
    3
    18
  • 亮点
    倪老师,如果进程间的虚拟内存空间独立,每个进程又有自己的页表,那么进程怎么获知其他进程占用的物理内存情况,怎么防止覆盖其他进程的物理内存块呢?

    作者回复: 1. 进程不需要获取其他进程的内存情况 2. 所有进程的内存都是由内核来管理的,内核保证内存的访问安全。比如,访问非法地址时,进程会panic

    2018-12-24
    12
  • ninuxer
    打卡day16 工作中,发生oom基本都是程序跑的,都甩给研发了~😂

    作者回复: 😂

    2018-12-24
    11
  • 李亮亮
    我的理解就是,Linux里面所有的概念皆结构(C语言的结构体),页表也是一种结构体,也就是数据,所以保存还是在内存里面。mmu其实就是一个硬件,它的作用就是找到某个虚拟地址到物理地址的映射,也就是找到正确的页表项。然后再交给CPU,当然也可以把找到的结果缓存在TBL中,这样CPU下次使用同一个虚拟地址就省了转换这步了,老师,不知道我理解的有错吗?

    作者回复: 对的,Linux也是一个程序,本质上还是数据结构+算法😊

    2019-02-28
    3
    10
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部