/proc/meminfo的理解&vmtouch使用介绍&内存碎片整理

free 和 meminfo查看内存情况。

linux的内存情况我们通常使用free命令来查看

$ free -m
             total       used       free     shared    buffers     cached
Mem:           925        388        537         25         27        207
-/+ buffers/cache:        153        771
Swap:           99          0         99

proc文件系统中的 meminfo文件包含关于系统对内存使用情况的信息。free命令就是读取这个文件来呈现当前系统包含物理内存和SWAP内存在内的空闲内存和已使用内存。

$ cat /proc/meminfo
MemTotal:         947732 kB     //总的可以使用的RAM大小,物理内存减去部分保留位和内核二进制代码。
MemFree:          550120 kB     //LowFree + HighFree的 总和 ,HighTotal, HighFree, LowTotal, LowFree 从内核V2.6.19版本开始支持,需配置 CONFIG_HIGHMEM宏。在当前我这个系统中应该是没有配置这个宏的。Highmem表示高于 ~860MB的物理内存,用于用户空间进程或者缓存页,内核必须使用特殊的方式才能访问 Highmem,故而访问起来会比lowmem更慢。HighFree就是空闲的HighMem, lowmem能做highmem能做的任何事,同时也能让内核方便地存储其数据结构。slab分配的内存都是基于这部分来的。当lowmem不足时,系统可能会出现异常。
MemAvailable:     728780 kB     
Buffers:           27804 kB         //给裸磁盘块使用的临时缓存空间,不能变得过大(比如超过20MB)
Cached:           212476 kB     //用于从磁盘读取的文件在内存中的缓存。不包括 SwapCached
SwapCached:            0 kB     //被swap到磁盘上的内存,如果已经被swap回来,但是仍在swapfile中也保留了一份。(在内存压力大的时候这样可以节省I/O,因为很可能这些内存马上又要被换出去)
Active:           221860 kB     // 更近和更频繁使用的内存,如果非必要不会被使用。
Inactive:         137452 kB     // 更没有被频繁使用的内存,更有可能被用于其他用途。
Active(anon):     119708 kB     
Inactive(anon):    25052 kB
Active(file):     102152 kB
Inactive(file):   112400 kB
Unevictable:           0 kB     //  需要支持配置了该宏CONFIG_UNEVICTABLE_LRU 
Mlocked:               0 kB     //  需要支持配置了该宏CONFIG_UNEVICTABLE_LRU 
SwapTotal:        102396 kB     // 总的可用SWAP空间。
SwapFree:         102396 kB     //未使用的SWAP空间。
Dirty:                 8 kB         //正在等待被写回磁盘的内存
Writeback:             0 kB     //正在被写回磁盘的内存
AnonPages:        118928 kB     // Non-file backed pages mapped into user-space page tables,并不与文件相关联的映射到用户空间的内存,在mmap系统调用中有MAP_ANONYMOUS 选项,从一个unix.stackexchange上一个答主的说法,malloc其实就是会去调用mmap去请求分配对应的内存,所以AnonPages可以理解为用户态进程最频繁使用的malloc出来的内存。
Mapped:            92468 kB     // 被映射到内存中的文件(mmap的方式),比如lib库
Shmem:             25732 kB     
Slab:              20004 kB         // 内核数据结构的缓存
SReclaimable:      10132 kB     // Slab的一部分,可能回被重新回收使用,比如caches
SUnreclaim:         9872 kB     // 即使内存不足,也不能被重新回收使用
KernelStack:        1864 kB     // 内核栈的内存
PageTables:         3712 kB     // 
NFS_Unstable:          0 kB     // 接收到 但还未持久化的NFS页。
Bounce:                0 kB       
WritebackTmp:          0 kB
CommitLimit:      576260 kB     // 这是当前系统上能允许被分配的内存总量,这个限制是否生效
与 /proc/sys/vm/overcommit_memory 参数中设置的模式相关,仅在 该类型被设置为模式2 ,即永远不触发 overcommit时,这个 阈值才会被应用。它的计算公式可以通过/proc/sys/vm/overcommit_memory来查看。 
// overcommit_memory 类型有3种,影响是否允许分配超过系统物理内存总大小的内存分配策略。0代表启发式overcommit, 1 Always overcommit 允许overcommit. 2 不允许overcommit,提交给系统的内存请求不允许超过总大小。

Committed_AS:    1254104 kB     // 当前系统中已经分配的内存,commited memory是已经分配给进程的内存总和的大小, 即使这些内存还没有被使用。比如一个进程请求分配了1GB的空间,但只使用了300MB的话,只会在这里计入300MB,即使实际分配了1GB的空间。
// 这1GB的内存已经被VM确认,随时可以分配给申请的进程。如果overcommit_memory设置为模式2,即严格限制overcommit的模式。超过CommitLimit的分配请求是不被允许的。这可以应用于如下场景,比如我们想要保证一个进程一旦对应已经成功分配了内存,就不会再因为内存不足而报错。
VmallocTotal:    1114112 kB     // vmalloc内存区域的总大小。vmalloc分配连续的虚拟内存,但可能是不连续的物理内存。只在分配大块内存空间不得已时使用。
VmallocUsed:           0 kB       // 已使用的vmalloc内存大小
VmallocChunk:          0 kB     // 大块的连续的空闲的vmalloc块
CmaTotal:           8192 kB     // 
CmaFree:            3728 kB

cached的产生

1、观察sftp下载文件内存中cache的影响
我们在通过下载一个10MB的文件前后分别使用free命令打印当前的内存状态。可以发现free的cached一栏增加了10MB的内存。那如何了解到是否就是这个文件的下载导致的呢?。我们可以使用vmtouch命令来进行查看。

~/package $ free -m
             total       used       free     shared    buffers     cached
Mem:           925        554        370         30         88        293
-/+ buffers/cache:        172        753
Swap:           99          0         99

~/package $ free -m
             total       used       free     shared    buffers     cached
Mem:           925        565        360         30         88        303
-/+ buffers/cache:        172        752
Swap:           99          0         99
vmtouch

2、vmtouch命令简介。

vmtouch是一个作者hoytech在github上开源的用于在unix和类unix系统上学习和控制文件系统缓存的工具。
下面是其帮助界面 https://github.com/hoytech/vmtouch/blob/master/vmtouch.pod
vmtouch的主要功能如下:

  • 查看一个文件或者目录的哪些部分在内存中
  • 手动把文件调入内存
  • 手动把文件清除出内存
  • 把文件锁住在内存中而不被换到磁盘上
./vmtouch-1.3.1/vmtouch -h
./vmtouch-1.3.1/vmtouch: no files or directories specified

vmtouch v1.3.1 - the Virtual Memory Toucher by Doug Hoyte
Portable file system cache diagnostics and control

Usage: vmtouch [OPTIONS] ... FILES OR DIRECTORIES ...

Options:
  -t touch pages into memory
  -e evict pages from memory
  -l lock pages in physical memory with mlock(2)
  -L lock pages in physical memory with mlockall(2)
  -d daemon mode
  -m <size> max file size to touch
  -p <range> use the specified portion instead of the entire file
  -f follow symbolic links
  -F don't crawl different filesystems
  -h also count hardlinked copies
  -i <pattern> ignores files and directories that match this pattern
  -I <pattern> only process files that match this pattern
  -b <list file> get files or directories from the list file
  -0 in batch mode (-b) separate paths with NUL byte instead of newline
  -w wait until all pages are locked (only useful together with -d)
  -P <pidfile> write a pidfile (only useful together with -l or -L)
  -v verbose
  -q quiet

3、vmtouch的常用使用场景。

我们下载vmtouch的1.3.1的版本编译后,查看刚才这个文件的的状态。可以看到 nmap这个文件在常驻页面中有2643个页,合计10M内存,通过getconf PAGESIZE 可以直到一个页的大小为4K。

~/package $ ./vmtouch-1.3.1/vmtouch ./nmap-7.93.tar.bz2
           Files: 1
     Directories: 0
  Resident Pages: 2643/2643  10M/10M  100%
         Elapsed: 0.001669 seconds

通过vmtouch -v ./ 可以递归查看某一个目录下所有文件的在内存中的暂存情况,可以用于在 调用drop_cache之后,发现cached中仍有很大的内存,确认具体是什么文件被加载到了内存,同时不能被清除出缓存。

通过vmtouch -t命令可以把文件提前加载到cache,实现预读的效果;通过vmtouch -e file 可以将文件的cache缓存清除出内存;通过vmtouch -l file 可以将文件的缓存锁在内存中不被换出。

3.1、 vmtouch -l file
首先来看使用vmtouch锁定文件到内存对 meminfo的影响,在meminfo中有一行为Mlocked,其表示被锁定在内存中的内存大小,即该块内存空间不会被交换到swap空间,也不会被回收。从如下的终端输出可以知道一开始Mlocked内存大小为0kB,经过vmtouch锁住之后,变为了10572kB,即10MB左右,恰好是锁住的 nmap-7.93.tar.bz2的文件的大小。

$cat /proc/meminfo
MemTotal:         947732 kB
...
Mlocked:               0 kB
...

 $ ./vmtouch-1.3.1/vmtouch -l nmap-7.93.tar.bz2
LOCKED 2643 pages (10M)
$ cat /proc/meminfo
MemTotal:         947732 kB
...
Mlocked:           10572 kB
...

lock可以用于将最常使用的小文件常驻到内存,避免被换出导致磁盘的读写。

3.2、 vmtouch -e file
通过vmtouch -e可以将这个文件的缓存清除出内存,我们使用free 命令cached的变化来观察其效果。在使用free之前cached缓存为 311MB,使用vmtouch -e 将文件nmap-7.93.tar.bz2清除出缓存后,free显示的cached缓存为301MB。可见vmtouch -e 之功效。

$ free -m
             total       used       free     shared    buffers     cached
Mem:           925        586        338         37         91        311
-/+ buffers/cache:        183        742
Swap:           99          0         99
$ ./vmtouch-1.3.1/vmtouch -e nmap-7.93.tar.bz2
           Files: 1
     Directories: 0
   Evicted Pages: 2643 (10M)
         Elapsed: 0.006798 seconds
$ free -m
             total       used       free     shared    buffers     cached
Mem:           925        576        349         37         91        301
-/+ buffers/cache:        183        742
Swap:           99          0         99

该处理流程可应用于在读写完文件之后,明确短时间内不会再加载文件,干预内核的缓存处理流程,快速将文件的缓存快速回收,用于其他流程内存的使用。

3.3、vmtouch -t file
vmtouch -t file可以把文件预加载到内存的cache。通过free -m可以看到执行vmtouch前后的cached内存的差异。

$ free -m
             total       used       free     shared    buffers     cached
Mem:           925        567        357         36         91        300
-/+ buffers/cache:        175        750
Swap:           99          0         99
$ ./vmtouch-1.3.1/vmtouch -t  nmap-7.93.tar.bz2
           Files: 1
     Directories: 0
   Touched Pages: 2643 (10M)
         Elapsed: 1.4855 seconds
$ free -m
             total       used       free     shared    buffers     cached
Mem:           925        577        348         36         91        310
-/+ buffers/cache:        174        750
Swap:           99          0         99

通过drop_cache的方式也可以手动释放内存,我们观察下使用drop_cache对cached缓存的影响。使用drop_cache必须拥有root权限。可以看到buffer和cached都进行了大量的释放,单独通过vmtouch观察 nmap文件在内存中的占用,可以看到占用大小为0.

# free -m
             total       used       free     shared    buffers     cached
Mem:           925        578        346         36         91        310
-/+ buffers/cache:        175        749
Swap:           99          0         99
#echo 3 > /proc/sys/vm/drop_caches
# free -m
             total       used       free     shared    buffers     cached
Mem:           925        279        645         36          1        114
-/+ buffers/cache:        164        761
Swap:           99          0         99

 $ ./vmtouch-1.3.1/vmtouch nmap-7.93.tar.bz2
           Files: 1
     Directories: 0
  Resident Pages: 0/2643  0/10M  0%
         Elapsed: 0.000964 seconds

vmtouch的实现主要是基于 mincore 和 mlock系统调用。mincore判断某个地址是否驻在内存中。mlock 将调用进程的虚拟地址空间锁在内存中,避免被swap交换出去。会体现在meminfo的Mlocked字段。

NAME
       mincore - determine whether pages are resident in memory

SYNOPSIS
       #include <unistd.h>
       #include <sys/mman.h>

       int mincore(void *addr, size_t length, unsigned char *vec);

MLOCK(2)                       Linux Programmer's Manual                       MLOCK(2)

NAME
       mlock, munlock, mlockall, munlockall - lock and unlock memory

SYNOPSIS
       #include <sys/mman.h>

       int mlock(const void *addr, size_t len);
       int munlock(const void *addr, size_t len);

内存碎片。

针对内存的另一个问题是内存碎片,我们可能会遇到即使不考虑cached和buffer的内存,free能查看到的内存也还有足够多,但malloc却出现失败,这种情况可能是由于我们申请了一块大内存。而由于linux的内存伙伴系统分配机制,导致出现了大量的内存碎片,而无法申请到整块的内存以满足需求。我们可以通过 cat /proc/buddyinfo 来查看内存碎片的情况。buddyinfo提供了信息用来确认内存碎片问题。这一行展示了不同大小的块的可用块数,块的大小通过 (2^order)* PAGE_SIZE来判断。
如果是4KB的PAGE_SIZE,则如下内存伙伴系统包含了 164个 4KB块,218个 8 KB块,。。。和 88个4MB块。

 $ cat /proc/buddyinfo
Node 0, zone   Normal    164    218     36    631    862    267     54     22      8      8     88

内核中的伙伴系统内存分配算法会将一个块均分成两个块,或者将两个连续的块合并成更高阶的大块。用来服务于分配请求,和对抗内存碎片的产生。order等级和列相对应,起始的order为0。
通过查看manpage可以了解到,如果内存严重碎片化,高阶的chunks数量会变成0,请求分配大块连续内存的请求会失败。

    /proc/buddyinfo
                ...
              If the memory is heavily fragmentated,  the  counters  for  higher  order
              chunks will be zero and allocation of large contiguous areas will fail.

通过 echo compact_memory可以手动触发内存整理。可以看到通过手动触发内存整理。4MB,2MB,1MB等大内存块的数量都有了明显的增加。

# cat /proc/buddyinfo
Node 0, zone   Normal     85    161     37    594    862    267     54     22      8      8     88

# echo 1 > /proc/sys/vm/compact_memory
# cat /proc/buddyinfo
Node 0, zone   Normal    135    283    101    163    122    107     72     54     21     16     95

后续

上面我们描述了查看内存分布情况 和 通过vmtouch和 drop_caches 等工具手动调节内存中缓存的方式,以及手动触发内存碎片整理的机制。那么内核回收cached的机制具体而言是什么样的呢?。这个待后续系统了解linux的内存管理子系统之后再做介绍。关于内核对内存的回收机制

参考:

meminfo:
https://lynxbee.com/understanding-proc-meminfo-analyzing-linux-memory-utilization/#.Y8i4nxVBxPY
anon-pages:
https://unix.stackexchange.com/questions/677006/what-is-anon-pages-in-memory
overcommit:
https://zhuanlan.zhihu.com/p/461093695
vmtouch:
https://www.cnblogs.com/coldplayerest/archive/2012/02/28/2371881.html
https://github.com/hoytech/vmtouch/blob/master/vmtouch.pod

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 是的,/proc/meminfo 包含了系统的内存信息。这个文件中包含了很多有用的信息,例如: - MemTotal:系统总内存大小 - MemFree:空闲内存大小 - Buffers:用于缓存的内存大小 - Cached:用于缓存的内存大小 - SwapTotal:交换区总大小 - SwapFree:交换区空闲大小 这些信息可以帮助你了解系统内存使用情况,并且帮助你分析系统性能问题。 ### 回答2: 不,/proc/meminfo文件并不包含所有的内存信息。它只提供了系统内存的一些关键指标和统计数据。例如,/proc/meminfo文件中可以获取到的信息包括: 1. MemTotal:系统总内存大小。 2. MemFree:可用的空闲内存大小。 3. Buffers:被用作内核缓冲的内存大小。 4. Cached:被用作文件缓存的内存大小。 5. SwapCached:被用作交换区缓存的内存大小。 6. SwapTotal:交换区总内存大小。 7. SwapFree:可用的交换区内存大小。 但是,/proc/meminfo文件并不包含每个进程或应用程序使用内存的详细信息。要获取特定进程的内存信息,需要使用其他工具(如top、htop或ps等)或者结合其他/proc目录下的文件进行查询。例如,/proc/[pid]/status文件提供了有关特定进程的内存信息,如VmRSS字段提供了进程当前使用的物理内存大小。 因此,尽管/proc/meminfo提供了一些重要的系统内存信息,但要获取更详细的内存信息,需要结合其他工具和文件来进行查询和分析。 ### 回答3: /proc/meminfo是一个特殊的文件,提供了关于系统内存使用情况的信息。它包含了大量的内存相关统计数据,但并不是包含所有的内存信息。 /proc/meminfo文件中包含的内容包括: 1. MemTotal:系统中总共的可用物理内存大小。 2. MemFree:系统中空闲的物理内存大小。 3. MemAvailable:系统中当前可用的物理内存大小,可以使用但不能保证完全空闲。 4. Buffers:用于存储块设备(硬盘等)的缓冲区大小。 5. Cached:用于存储文件缓存的大小。 6. SwapCached:用于存储交换空间中的缓存大小。 7. SwapTotal:系统中总共的交换空间大小。 8. SwapFree:系统中空闲的交换空间大小。 9. Dirty:等待写回磁盘的内存大小。 10. Writeback:正在写回磁盘的内存大小。 11. AnonPages:匿名页面(未映射到文件)的内存大小。 12. Mapped:被映射到进程地址空间的文件的内存大小。 尽管/proc/meminfo提供了大量内存统计数据,但它并不包含所有的内存信息。例如,它不提供每个进程或线程独占的内存使用情况,也无法提供详细的内存分配信息。 要获取更多细节的内存信息,可以使用其他工具和命令,如top、free、vmstat等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值