zoukankan      html  css  js  c++  java
  • meminfo详解

     Linux查看内存使用情况,可以查看/proc/meminfo和使用free命令


    [root@localhost proc]# cat /proc/stat/meminfo

    MemTotal: 8009264 kB     总内存
    MemFree: 1784144 kB      空闲内存数
    MemAvailable: 4004984 kB  可用内存数
    Buffers: 2140 kB   缓冲
    Cached: 2462260 kB  缓存
    SwapCached: 0 kB    交换缓存
    Active: 4132544 kB
    Inactive: 1772736 kB
    Active(anon): 3501548 kB
    Inactive(anon): 38916 kB
    Active(file): 630996 kB
    Inactive(file): 1733820 kB
    Unevictable: 0 kB
    Mlocked: 0 kB
    SwapTotal: 2097148 kB
    SwapFree: 2097148 kB
    Dirty: 16 kB
    Writeback: 0 kB
    AnonPages: 3440884 kB
    Mapped: 60888 kB
    Shmem: 99580 kB
    Slab: 188616 kB
    SReclaimable: 154900 kB
    SUnreclaim: 33716 kB
    KernelStack: 4512 kB
    PageTables: 12644 kB
    NFS_Unstable: 0 kB
    Bounce: 0 kB
    WritebackTmp: 0 kB
    CommitLimit: 6101780 kB
    Committed_AS: 4107308 kB
    VmallocTotal: 34359738367 kB
    VmallocUsed: 157924 kB
    VmallocChunk: 34359341052 kB
    HardwareCorrupted: 0 kB
    AnonHugePages: 3227648 kB
    CmaTotal: 0 kB
    CmaFree: 0 kB
    HugePages_Total: 0
    HugePages_Free: 0
    HugePages_Rsvd: 0
    HugePages_Surp: 0
    Hugepagesize: 2048 kB
    DirectMap4k: 83904 kB
    DirectMap2M: 4110336 kB
    DirectMap1G: 6291456 kB

    [root@localhost proc]# free
    total used free shared buff/cache available
    Mem: 8009264 3572252 1784012 99580 2653000 4004868
    Swap: 2097148 0 2097148

    我们可以从 /proc/meminfo 中查看内核使用内存情况的各种信息。

    一个 /proc/meminfo 的内容看起来是这样的:

    cat /proc/meminfo |nl
    
     1      MemTotal:        3814108 kB
     2      MemFree:          111908 kB
     3      MemAvailable:     394844 kB
     4      Buffers:           22976 kB
     5      Cached:           291436 kB
     6      SwapCached:        15480 kB
     7      Active:          1634948 kB
     8      Inactive:         784896 kB
     9      Active(anon):    1487400 kB
    10      Inactive(anon):   474008 kB
    11      Active(file):     147548 kB
    12      Inactive(file):   310888 kB
    13      Unevictable:           0 kB
    14      Mlocked:               0 kB
    15      SwapTotal:       8388604 kB
    16      SwapFree:        8238844 kB
    17      Dirty:             22280 kB
    18      Writeback:             0 kB
    19      AnonPages:       2103892 kB
    20      Mapped:          1262612 kB
    21      Shmem:             81684 kB
    22      Slab:              99048 kB
    23      SReclaimable:      53432 kB
    24      SUnreclaim:        45616 kB
    25      KernelStack:        8352 kB
    26      PageTables:        24152 kB
    27      NFS_Unstable:          0 kB
    28      Bounce:                0 kB
    29      WritebackTmp:          0 kB
    30      CommitLimit:    10295656 kB
    31      Committed_AS:    6235812 kB
    32      VmallocTotal:   34359738367 kB
    33      VmallocUsed:           0 kB
    34      VmallocChunk:          0 kB
    35      HardwareCorrupted:     0 kB
    36      AnonHugePages:         0 kB
    37      ShmemHugePages:        0 kB
    38      ShmemPmdMapped:        0 kB
    39      HugePages_Total:       0
    40      HugePages_Free:        0
    41      HugePages_Rsvd:        0
    42      HugePages_Surp:        0
    43      Hugepagesize:       2048 kB
    44      DirectMap4k:      106112 kB
    45      DirectMap2M:     3858432 kB
    

    可以看出,这里的内核信息特别多,有些含义很难理解。

    下面就来尝试解释一下这些行的意义:

    MemTotal

    总共安装的物理内存容量

    MemFree

    当前空闲的内存量

    MemAvailable

    Buffers / Cached

    buffers + cached的值就是可以使用的磁盘告诉缓存的大小。

    buffers + cached = Active(file) + Inactive(file) + Shmem

    SwapCached

    记录在交换缓存上的内容容量。

    所谓交换缓存是指,在换入某个内存页之后,物理磁盘上的交换空间依然保留同样的数据,这样的内存页会记录在"交换缓存"的列表上。 这样的好处在于,当需要再次换出记录在交换缓存中的的内存页时,可以直接使用交换分区中保存的内容,而无需将内存再次写入交换空间。

    当该交换空间上的其他数据被换出,或是换入内存中的数据被改写,则交换缓存上的记录会被清空。

    Active

    等于Active(anon) + Active(file)的和

    Inactive

    等于Inactive(anon) + Inactive(file)的和

    Active(anon) / Inactive(anon) / Active(file) / Inactive(file)

    括号中为anon的内存为匿名内存,括号中为file的内存为file-backed内存,这两个内存的区别在于,物理内存的内容是否与物理磁盘上的文件相关联。

    其中,匿名内存就是进程中堆上分配的内存,是用malloc分配的内存。

    而file-backed内存为磁盘高速缓存的内存空间和“文件映射(将物理磁盘上的文件内容与用户进程的逻辑地址直接关联)”的内存空间,其中的内容与物理磁盘上的文件相对应。

    而Active和Inactive的区别在于内存空间中是否包含最近被使用过的数据。当物理内存不足,不得不释放正在使用的内存空间时,会优先释放Inactive的内存空间。

    Linux内核中使用4类LRU表来分别记录对应的这4类内存页,内存页一般以4K为一页。

    Unevictable

    有些内存页是不能被释放的,这些内存页不能放在LRU表中,而是记录到Unevictable标中

    Mlocked

    SwapTotal

    交换空间的总大小

    SwapFree

    交换空间的剩余容量

    Dirty

    脏数据,在磁盘缓冲区中尚未写入物理磁盘的内存大小

    Writeback

    AnonPages

    Linux内核中存在一个rmap(reverse mapping)机制,负责管理匿名内存中每一个物理内存页映射到哪个进程的哪个逻辑地址这样的信息。 这个rmap中记录的内存页总和就是AnonPages的值。

    Mapped

    Shmem

    tmpfs所使用的内存.

    tmpfs即利用物理内存来提供RAM磁盘的功能。在tmpfs上保存文件时,文件系统会暂时将它们保存到磁盘高速缓存上,因此它是属于磁盘高速缓存对应的"buffers+cached"一类。 但是由于磁盘上并没有与之对应的内容,因此它并未记录在File-backed内存对应的LRU列表上,而是记录在匿名内存的LRU表上。 这就是 buffers + cached = Active(file) + Inactive(file) + Shmem 公式的由来

    Slab

    由"Slab分配器"分配的总量。Slab分配器针对一些经常分配并释放的对象(如进程描述符)统计各种数据类型的汇总信息,然后为每种数据类型创建多个由多个内存页组成的Slab(这些Slab组成一个Slab列表)。 再在Slab内部划分成一个个相应数据类型的对象。

    当内核要使用某种类型的数据结构时,就从对应的slab列表中分配一个对象出去,而当要释放时,将其重新保存在Slab列表中,从而避免内存碎片。

    当可供使用的对象不足时,会使用空闲的内存页来创建并添加新的Slab到对应对象的Slab列表中。 相反,若Slab中所有对象都被内核回收,即所有对象都未使用时,根据需要也可以回收Slab,释放成空闲内存。

    从 /proc/slabinfo 中我们可以查看每个Slab的信息:

    sudo cat /proc/slabinfo |head
    
    slabinfo - version: 2.1
    # name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
    nf_conntrack          27     72    320   12    1 : tunables    0    0    0 : slabdata      6      6      0
    ovl_inode             46     46    688   23    4 : tunables    0    0    0 : slabdata      2      2      0
    fuse_request          40     40    400   20    2 : tunables    0    0    0 : slabdata      2      2      0
    fuse_inode            19     19    832   19    4 : tunables    0    0    0 : slabdata      1      1      0
    xfs_dqtrx              0      0    528   15    2 : tunables    0    0    0 : slabdata      0      0      0
    xfs_rui_item           0      0    672   12    2 : tunables    0    0    0 : slabdata      0      0      0
    xfs_rud_item           0      0    152   26    1 : tunables    0    0    0 : slabdata      0      0      0
    xfs_ili             4486   4488    168   24    1 : tunables    0    0    0 : slabdata    187    187      0
    

    其中:

    name
    对象名称
    active_objs
    处于活跃状态的对象个数
    num_objs
    slab列表中的总对象数量
    objperslab
    一个slab中包含的对象个数
    pageperslab
    每个slab占用的内存页数
    num_slabs
    slab列表中slab的个数
    active_slabs
    处于活跃状态的slab个数

    SReclaimable

    不存在活跃对象,可以回收的Slab容量

    SUnreclaim

    对象处于活跃状态,不能被回收的Slab容量

    KernelStack

    KernelStack是内核代码使用的堆栈区域。

    由于Linux内核中用户进程在运行过程中需要不断切换,因此内核需要为每个用户进程都设置各自的堆栈区域。 因此,每启动一个新进程,KernelStack的值都会增加。

    PageTables

    PageTables就是页表,用于存储各个用户进程的逻辑地址和物理地址的变换关系,它本身也是一个内存区域。

    NFS_Unstable

    Bounce

    WritebackTmp

    CommitLimit

    Committed_AS

    VmallocTotal

    Linux使用内存时,除了使用Slab中配置的对象外,还能直接将空闲内存页映射到逻辑地址上。

    这个容量指的是,理论上内核内部可以用来映射的逻辑地址的范围。这个值非常大,但并非实际使用的物理内存

    VmallocUsed

    实际上,Linux将空闲内存页映射到逻辑地址上的容量。

    值得说明的是,这个容量除了物理内存上所作的映射外,也包括诸如视频卡这样的外部设备内存所作的映射,这类映射叫做"ioremap"

    我们可以通过 /proc/vmallocainfo 查看VmallocUsed中包含内存区域的详情

    cat /proc/vmallocinfo |head
    
    0x000000008088114a-0x000000001aecb69b    8192 acpi_os_map_iomem+0x14c/0x180 phys=0x00000000bf6bd000 ioremap
    0x000000001aecb69b-0x0000000086f9fed7    8192 acpi_os_map_iomem+0x14c/0x180 phys=0x00000000bf6e4000 ioremap
    0x0000000086f9fed7-0x000000006fbc598c    8192 acpi_os_map_iomem+0x14c/0x180 phys=0x00000000bf6e2000 ioremap
    0x000000006fbc598c-0x00000000636e4cf9   12288 acpi_os_map_iomem+0x14c/0x180 phys=0x00000000bf6e2000 ioremap
    0x00000000636e4cf9-0x000000005464ab58    8192 hpet_enable+0x34/0x2c1 phys=0x00000000fed00000 ioremap
    0x000000005464ab58-0x00000000396cc741   12288 alloc_large_system_hash+0x194/0x257 pages=2 vmalloc N0=2
    0x00000000396cc741-0x0000000038ec28d8    8192 bpf_prog_alloc+0x40/0xb0 pages=1 vmalloc N0=1
    0x0000000038ec28d8-0x000000002f686ade   65536 acpi_os_map_iomem+0x14c/0x180 phys=0x00000000bf6bd000 ioremap
    0x000000002f686ade-0x00000000fee69f16 4198400 alloc_large_system_hash+0x194/0x257 pages=1024 vmalloc vpages N0=1024
    0x00000000fee69f16-0x00000000362aad15 2101248 alloc_large_system_hash+0x194/0x257 pages=512 vmalloc N0=512
    

    其中

    • 第一列为逻辑地址的范围
    • 第二列为容量,以字节为单位
    • 最后一列若为ioremap,说明该映射为ioremap

    所以要计算除ioremap外物理内存的映射量,可以这么计算

    sudo cat /proc/vmallocinfo |grep -v "ioremap" |awk '{total=total+$2};END{print total}'
    
    107110400
    

    VmallocChunk

    HardwareCorrupted

    AnonHugePages

    ShmemHugePages

    ShmemPmdMapped

    HugePages_Total

    HugePages_Free

    HugePages_Rsvd

    HugePages_Surp

    Hugepagesize

    DirectMap4k

    DirectMap2M

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

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

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

    从结果来看,/proc/meminfo里的MemTotal、MemFree、Buffers、Cached是能够分别和free输出结果的“Mem”行一一对应的。

    名词解释

      这里先解释下几个关键词:

    1、MemTotal:内存总数

      系统从加电开始到引导完成,BIOS等要保留一些内存,内核要保留一些内存,最后剩下可供系统支配的内存就是MemTotal。这个值在系统运行期间一般是固定不变的。

    2、MemFree:空闲内存数

      表示系统尚未使用的内存。MemUsed=MemTotal-MemFree就是已被用掉的内存。

    3、MemAvailable:可用内存数

      应用程序可用内存数。系统中有些内存虽然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可以回收,所以MemFree不能代表全部可用的内存,这部分可回收的内存加上MemFree才是系统可用的内存,即:MemAvailable≈MemFree+Buffers+Cached,它是内核使用特定的算法计算出来的,是一个估计值。它与MemFree的关键区别点在于,MemFree是说的系统层面,MemAvailable是说的应用程序层面。

    4、Buffer:缓冲区内存数

    5、Cache:缓存区内存数

    6、Shared:多个进程共享的内存空间,不常用,暂不讨论。

      Buffer与Cache的区别:

    这里说下buffer与cache的区别,首先,从字面意义上讲,buffer是缓冲的意思,cache是缓存的意思。举个现实中的例子,比说铁道头上像弹簧一样的东西,就叫缓冲;部署在森林里的存应急物资的保管箱,名叫“Food Cache”,类似一种保存箱。  其次,常见的说法,叫write-buffer和read-cache,buffer一般用作写操作上,cache一般用在读操作上,不过也不是一成不变的;  举例说明,每秒要写100次硬盘,对系统冲击很大,浪费了大量时间在忙着处理开始写和结束写这两件事嘛。用buffer暂存起来,变成每10秒写一次硬盘,对系统的冲击就很小,写入效率高了;Cache 是为了弥补高速设备和低速设备的鸿沟而引入的中间层,最终起到加快取速度的作用。比如你一个很复杂的计算做完了,下次还要用结果,就把结果放手边一个好拿的地方存着,下次不用再算了,加快了数据取用的速度。(可以参考知乎上的回答:https://www.zhihu.com/question/26190832

    计算公式:

    参照free的输出结果,这里有几个计算公式:

    root@prometheus-02:~# free
                 total       used       free     shared    buffers     cached
    Mem:      16433020    1827360   14605660        740     203540    1051400
    -/+ buffers/cache:     572420   15860600
    Swap:      8388604          0    8388604
     

    为了直观说明,把第2行,Mem的行我这里称作OS Mem,第三行 buffers/cache行,称作APP buffer/cache:

    OS Mem total = OS Mem used + OS Mem free

    APP buffers/cache used = OS Mem used - OS Mem buffers - OS Mem cached

    APP buffers/cache free = OS Mem free + OS Mem buffers + OS Mem cached

    APP buffers/cache total = APP buffers/cache used + APP buffers/cache free = OS Mem total

  • 相关阅读:
    内网穿透教程
    深入浅出 TCP/IP 协议栈
    STM32CUBEMX配置RTC闹钟
    RT-Thread STM32 系列 BSP 制作教程
    RT-Thread 在stm小内存系列产品的nano+msh完整移植教程
    C语言字符串与数字相互转换
    SD卡 TF卡 接口引脚定义
    定位数据格式
    安信可ESP-12F连接阿里云教程
    电脑使用网络调试助手连接阿里云步骤
  • 原文地址:https://www.cnblogs.com/sea520/p/12680525.html
Copyright © 2011-2022 走看看