• Linux基础知识:认识一下内存


    1、什么是内存泄漏?

            对内存来说,如果之分配内存给程序,而程序使用完不进行释放,就会造成内存泄漏,甚至耗尽系统内存,需要调用free()或unmap(),来释放这些内存。

    2、内存紧张,系统的处理机制:

         2.1   回收缓存,比如使用 LRU(Least Recently Used)算法,回收最近使用最少的内存页面;

         2.2    回收不常访问的内存,把不常用的内存通过交换分区(swap)直接写到磁盘中;swap 其实就是把一块磁盘空间当成内存来用。它可以把进程暂时不用的数据存储到磁盘中(这个过程称为换出),当进程访问这些内存时,再从磁盘读取这些数据到内存中(这个过程称为换入)。所以,你可以发现,Swap 把系统的可用内存变大了。不过要注意,通常只在内存不足时,才会发生 Swap 交换。并且由于磁盘读写的速度远比内存慢,Swap 会导致严重的内存性能问题。

        2.3   杀死进程,内存紧张时系统还会通过 OOM(Out of Memory),直接杀掉占用大量内存的进程。  OOM(Out of Memory),其实是内核的一种保护机制。它监控进程的内存使用情况,并且使用 oom_score 为每个进程的内存使用情况进行评分:

            2.3.2  一个进程运行占用的 CPU 越多,oom_score 就越小。

            2.3.2  一个进程消耗的内存越大,oom_score 就越大;代表消耗的内存越多,也就越容易被OOM杀死,从而可以更好的保护系统。

            2.3.3   为了实际工作的需要,可以通过 /proc 文件系统,手动设置进程的 oom_adj ,从而调整进程的 oom_score。

            2.3.4   oom_adj 的范围是 [-17, 15],数值越大,表示进程越容易被 OOM 杀死;数值越小,表示进程越不容易被 OOM 杀死,其中 -17 表示禁止 OOM。

            2.3.5 比如用下面的命令,可以把 sshd 进程的 oom_adj 调小为 -16,这样, sshd 进程就不容易被 OOM 杀死。

    echo -16 > /proc/$(pidof sshd)/oom_adj

    3、查看内存使用情况

         3.1 Free(显示整个系统内存使用情况)命令的使用,尤其注意一下,最后一列的可用内存 available 。available 不仅包含未使用内存,还包括了可回收的缓存,所以一般会比未使用内存更大。不过,并不是所有缓存都可以回收,因为有些缓存可能正在使用中。

    1. # 注意不同版本的free输出可能会有所不同
    2. $ free
    3. total used free shared buff/cache available
    4. Mem: 8169348 263524 6875352 668 1030472 7611064
    5. Swap: 0 0 0
    6. 第一列,total 是总内存大小;
    7. 第二列,used 是已使用内存的大小,包含了共享内存;
    8. 第三列,free 是未使用内存的大小;
    9. 第四列,shared 是共享内存的大小;
    10. 第五列,buff/cache 是缓存和缓冲区的大小;最后一列,available 是新进程可用内存的大小。

          3.2 查看进程使用情况,可以用top或者ps等工具。

    1. # 按下M切换到内存排序
    2. $ top
    3. ...
    4. KiB Mem : 8169348 total, 6871440 free, 267096 used, 1030812 buff/cache
    5. KiB Swap: 0 total, 0 free, 0 used. 7607492 avail Mem
    6. PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
    7. 430 root 19 -1 122360 35588 23748 S 0.0 0.4 0:32.17 systemd-journal
    8. 1075 root 20 0 771860 22744 11368 S 0.0 0.3 0:38.89 snapd
    9. 1048 root 20 0 170904 17292 9488 S 0.0 0.2 0:00.24 networkd-dispat
    10. 1 root 20 0 78020 9156 6644 S 0.0 0.1 0:22.92 systemd
    11. 12376 azure 20 0 76632 7456 6420 S 0.0 0.1 0:00.01 systemd
    12. 12374 root 20 0 107984 7312 6304 S 0.0 0.1 0:00.00 sshd
    13. ...
    14. VIRT 是进程虚拟内存的大小,只要是进程申请过的内存,即便还没有真正分配物理内存,也会计算在内。
    15. RES 是常驻内存的大小,也就是进程实际使用的物理内存大小,但不包括 Swap 和共享内存。
    16. SHR 是共享内存的大小,比如与其他进程共同使用的共享内存、加载的动态链接库以及程序的代码段等。
    17. %MEM 是进程使用物理内存占系统总内存的百分比。

          3.3 在查看Top输出时,还要注意两点

                    3.3.1 第一,虚拟内存通常并不会全部分配物理内存。从上面的输出,可以发现每个进程的虚拟内存都比常驻内存大得多。

                    3.3.2 第二,共享内存 SHR 并不一定是共享的,比方说,程序的代码段、非共享的动态链接库,也都算在 SHR 里。当然,SHR 也包括了进程间真正共享的内存。所以在计算多个进程的内存使用时,不要把所有进程的 SHR 直接相加得出结果。

    本文整理自极客时间 倪朋飞:《Linux性能优化实战》                  

  • 相关阅读:
    Spring源码:Bean生命周期(三)
    typescript: 类型“NodeListOf<xxx>”必须具有返回迭代器的 “[Symbol.iterator]()“ 方法。ts(2488)
    【ffmpeg】YUV实践
    【云计算与数据中心规划】【期末复习题】
    A37 STM32_HAL库函数 之PCD通用驱动 -- C-- 所有函数的介绍及使用
    基于白鲸优化算法的函数寻优算法
    Maven生命周期与插件
    OpenTelemetry 深度定制:跨服务追踪的实战技巧
    (三)Ansible-命令模块
    Oracle rac环境的数据库导入操作记录
  • 原文地址:https://blog.csdn.net/qq_39507436/article/details/126005539