Linux性能优化实战
倪朋飞
微软资深工程师,Kubernetes项目维护者
立即订阅
23395 人已学习
课程目录
已完结 64 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (2讲)
开篇词 | 别再让Linux性能问题成为你的绊脚石
免费
01 | 如何学习Linux性能优化?
CPU 性能篇 (13讲)
02 | 基础篇:到底应该怎么理解“平均负载”?
03 | 基础篇:经常说的 CPU 上下文切换是什么意思?(上)
04 | 基础篇:经常说的 CPU 上下文切换是什么意思?(下)
05 | 基础篇:某个应用的CPU使用率居然达到100%,我该怎么办?
06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?
07 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(上)
08 | 案例篇:系统中出现大量不可中断进程和僵尸进程怎么办?(下)
09 | 基础篇:怎么理解Linux软中断?
10 | 案例篇:系统的软中断CPU使用率升高,我该怎么办?
11 | 套路篇:如何迅速分析出系统CPU的瓶颈在哪里?
12 | 套路篇:CPU 性能优化的几个思路
13 | 答疑(一):无法模拟出 RES 中断的问题,怎么办?
14 | 答疑(二):如何用perf工具分析Java程序?
内存性能篇 (8讲)
15 | 基础篇:Linux内存是怎么工作的?
16 | 基础篇:怎么理解内存中的Buffer和Cache?
17 | 案例篇:如何利用系统缓存优化程序的运行效率?
18 | 案例篇:内存泄漏了,我该如何定位和处理?
19 | 案例篇:为什么系统的Swap变高了(上)
20 | 案例篇:为什么系统的Swap变高了?(下)
21 | 套路篇:如何“快准狠”找到系统内存的问题?
22 | 答疑(三):文件系统与磁盘的区别是什么?
I/O 性能篇 (10讲)
23 | 基础篇:Linux 文件系统是怎么工作的?
24 | 基础篇:Linux 磁盘I/O是怎么工作的(上)
25 | 基础篇:Linux 磁盘I/O是怎么工作的(下)
26 | 案例篇:如何找出狂打日志的“内鬼”?
27 | 案例篇:为什么我的磁盘I/O延迟很高?
28 | 案例篇:一个SQL查询要15秒,这是怎么回事?
29 | 案例篇:Redis响应严重延迟,如何解决?
30 | 套路篇:如何迅速分析出系统I/O的瓶颈在哪里?
31 | 套路篇:磁盘 I/O 性能优化的几个思路
32 | 答疑(四):阻塞、非阻塞 I/O 与同步、异步 I/O 的区别和联系
网络性能篇 (13讲)
33 | 关于 Linux 网络,你必须知道这些(上)
34 | 关于 Linux 网络,你必须知道这些(下)
35 | 基础篇:C10K 和 C1000K 回顾
36 | 套路篇:怎么评估系统的网络性能?
37 | 案例篇:DNS 解析时快时慢,我该怎么办?
38 | 案例篇:怎么使用 tcpdump 和 Wireshark 分析网络流量?
39 | 案例篇:怎么缓解 DDoS 攻击带来的性能下降问题?
40 | 案例篇:网络请求延迟变大了,我该怎么办?
41 | 案例篇:如何优化 NAT 性能?(上)
42 | 案例篇:如何优化 NAT 性能?(下)
43 | 套路篇:网络性能优化的几个思路(上)
44 | 套路篇:网络性能优化的几个思路(下)
45 | 答疑(五):网络收发过程中,缓冲区位置在哪里?
综合实战篇 (13讲)
46 | 案例篇:为什么应用容器化后,启动慢了很多?
47 | 案例篇:服务器总是时不时丢包,我该怎么办?(上)
48 | 案例篇:服务器总是时不时丢包,我该怎么办?(下)
49 | 案例篇:内核线程 CPU 利用率太高,我该怎么办?
50 | 案例篇:动态追踪怎么用?(上)
51 | 案例篇:动态追踪怎么用?(下)
52 | 案例篇:服务吞吐量下降很厉害,怎么分析?
53 | 套路篇:系统监控的综合思路
54 | 套路篇:应用监控的一般思路
55 | 套路篇:分析性能问题的一般步骤
56 | 套路篇:优化性能问题的一般方法
57 | 套路篇:Linux 性能工具速查
58 | 答疑(六):容器冷启动如何性能分析?
加餐篇 (4讲)
加餐(一) | 书单推荐:性能优化和Linux 系统原理
加餐(二) | 书单推荐:网络原理和 Linux 内核实现
用户故事 | “半路出家 ”,也要顺利拿下性能优化!
用户故事 | 运维和开发工程师们怎么说?
结束语 (1讲)
结束语 | 愿你攻克性能难关
Linux性能优化实战
登录|注册

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

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

内存映射

说到内存,你能说出你现在用的这台计算机内存有多大吗?我估计你记得很清楚,因为这是我们购买时,首先考虑的一个重要参数,比方说,我的笔记本电脑内存就是 8GB 的 。
我们通常所说的内存容量,就像我刚刚提到的 8GB,其实指的是物理内存。物理内存也称为主存,大多数计算机用的主存都是动态随机访问内存(DRAM)。只有内核才可以直接访问物理内存。那么,进程要访问内存时,该怎么办呢?
Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。这样,进程就可以很方便地访问内存,更确切地说是访问虚拟内存。
虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同字长(也就是单个 CPU 指令可以处理数据的最大长度)的处理器,地址空间的范围也不同。比如最常见的 32 位和 64 位系统,我画了两张图来分别表示它们的虚拟地址空间,如下所示:
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Linux性能优化实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(85)

  • 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
    71
  • 我来也
    [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
    27
  • 梦回汉唐
    1、调用c标准库的都是用户空间的调用,用户空间的内存分配都是基于buddy算法(伙伴算法),并不涉及slab
    2、brk()方式之所以会产生内存碎片,是由于brk分配的内存是推_edata指针,从堆的低地址向高地址推进。这种情况下,如果高地址的内存不释放,低地址的内存是得不到释放的
    3、mmap()方式分配的内存,是在堆与栈之间的空闲区域分配虚拟内存,直接拿到的是内存地址,可以直接操作内存的释放

    上述的都是在用户空间发生的行为,只有在内核空间,内核调用kmalloc去分配内存的时候,才会涉及到slab

    作者回复: 👍

    2019-03-27
    20
  • espzest
    用户空间malloc不会使用slab机制吧,slab是内核空间的,对不?

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

    2018-12-24
    12
  • 虎虎❤️
    请教老师几个问题

    1. 当内存紧张时,系统通过三种机制回收内存。第二种换页比较好理解, 但是第一种LRU回收内存页怎么理解?回收后的页去哪了?如果直接删除会导致程序出问题吗?

    2. OOM的分数是参照进程的实际消耗内存还是虚拟内存大小?

    3. 进程启动时,是不是需要分配一个最小的内存?都包括什么呢?如何确定最小的内存是多大呢?比如我在k8s里设置container的request值,我希望是能容乃下这个container的最小内存,有没有办法计算呢?

    有的问题比较小白,望老师包含。如果无法简短的回答,能否推荐些资料呢?谢谢
    2018-12-24
    8
  • 划时代
    我的分析步骤:使用top和ps查询系统中大量占用内存的进程,使用cat /proc/[pid]/status和pmap -x pid查看某个进程使用内存的情况和动态变化。

    作者回复: 👍

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

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

    2018-12-24
    6
  • 圣域烈焰
    请教一个问题,使用free命令的时候,看到的buffer、cache和shared有什么区别?

    作者回复: 下一期讲 buffer 和 cache

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

    作者回复: 😂

    2018-12-24
    3
  • Griffin
    hmmm,我要提问。老师,我的开发机是macbook。内存是16G。但是经常出现已12G,swap用了3-4G。我平时没用ide就tmux+vim,内存大户就一个dorker和chrome。卡的我不得了,每次都只能重启来缓解。发现有个windowserver占用很多。感觉16G内存开发应该完全够用才对啊,有没有mac下可以禁用swap?让内存不够的时候优先回收缓存和不常用的内存,而不是滥用swap?

    作者回复: MAC还真不了解。接下来还有swap的文章,到时候可以参考试试

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

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

    2018-12-24
    2
  • 大甜菜
    malloc本身不会使用slab
    只有内核中使用kmalloc才回通过slab分配内存

    作者回复: 嗯嗯,是的,谢谢指出

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

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

    2018-12-24
    2
  • 靠人品去赢
    看的很爽这篇文章,之前知道一点操作系统关于内存的分配使用,内存映射管理物理内存和虚拟内存的对应关系,也知道页。但是还没见过将二者串起来,好多疑问解决。
    我们经常说的多少位长,到底有什么区别?就是虚拟内存空间大小,以及空间的分配区别。
    虚拟内存和物理内存的分配,怎么让物理内存能及时跟进程需要的虚拟内存交互对应起来?内核态和用户态的切换,知道进程有个虚拟地址,一个是用户的,一个是内核的,当调用进程的某些内存发现维护的内存映射没有对应的,及切换到内核态,内核把对应的虚拟内存放进去物理内存,再切回来用户态,进程继续,妙。
    2019-07-11
    1
  • 周曙光爱学习
    虚拟内存中只有内核空间能访问物理内存吗?也就是说只有内核空间才会有页表与物理内存关联吗?那用户空间的虚拟内存怎么玩?

    作者回复: 虚拟内存由内核来管理,进程不能直接访问物理内存

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

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

    2019-02-28
    1
  • 湖海散人
    分配虚拟内存使用的是brk 和 mmap,在真正使用内存的时候引起缺页中断再分配真正的物理内存

    请问,那这里的分配物理内存的方式是怎样的啊,是按照什么机制来进行分配物理内存,虚拟内存有内存的分段等一系列机制在管理,那物理内存呢? 在使用brk分配小内存和使用mmap分配大内存的时候,对应的物理内存的分配策略是怎样的啊

    作者回复: 物理内存是由内核来统一管理的,内核通过kmalloc、页、SLAB 等多种机制来管理不同用途的内存

    2019-02-28
    1
  • 如果
    DAY15,内存工作原理有点难理解~~
    2019-01-03
    1
  • Geek_37593b
    先打卡,地铁上。
    2018-12-28
    1
  • 子轩Zixuan
    cpu和内存应该是出问题频率最高的两块内容了,期待内存篇实战

    作者回复: 马上就开始😊

    2018-12-24
    1
收起评论
85
返回
顶部