内存整体信息

查看内存剩余free:

e0005055@ibudev20:~$ free
              total        used        free      shared  buff/cache   available
Mem:       32791720    19499516      935896        2552    12356308    12824920
Swap:       2097148        2048     2095100

其中,total ≈ used+available

查看buddy信息buddyinfo:

~$ sudo cat /proc/buddyinfo
Node 0, zone      DMA      1      1      1      0      2      1      1      0      1      1      3
Node 0, zone    DMA32   7437   3964   2908    225     83     19      8      2      0      0      0
Node 0, zone   Normal  64044  11133  27161    593    116      3      0      0      0      0      0

从buddy可以看到mem区域和对应的使用情况。64系统因为寻址空间大,就不存在高端内存了。

查看slab信息slabinfo:

~$ sudo cat /proc/slabinfo
slabinfo - version: 2.1
# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail>
uvm_tools_event_tracker_t      0      0   1128   29    8 : tunables    0    0    0 : slabdata      0      0      0
uvm_range_group_range_t      0      0     96   42    1 : tunables    0    0    0 : slabdata      0      0      0
uvm_va_block_context_t      0      0   1472   22    8 : tunables    0    0    0 : slabdata      0      0      0
uvm_va_block_gpu_state_t      0      0    432   37    4 : tunables    0    0    0 : slabdata      0      0      0
uvm_va_block_t         0      0    784   20    4 : tunables    0    0    0 : slabdata      0      0      0
uvm_va_range_t         0      0   1912   17    8 : tunables    0    0    0 : slabdata      0      0      0
btrfs_delayed_node      0      0    312   26    2 : tunables    0    0    0 : slabdata      0      0      0
btrfs_ordered_extent      0      0    416   39    4 : tunables    0    0    0 : slabdata      0      0      0
btrfs_inode            0      0   1168   28    8 : tunables    0    0    0 : slabdata      0      0      0
ufs_inode_cache        0      0    808   20    4 : tunables    0    0    0 : slabdata      0      0      0
qnx4_inode_cache       0      0    680   24    4 : tunables    0    0    0 : slabdata      0      0      0

查看zone信息zoneinfo:

:~$ sudo cat /proc/zoneinfo
Node 0, zone      DMA
...
Node 0, zone   Normal
  pages free     201343
        min      15777
        low      23415
        high     31053
        spanned  7790592
        present  7790592
        managed  7640422
        protection: (0, 0, 0, 0, 0)
      nr_free_pages 201343
      nr_zone_inactive_anon 65772
      nr_zone_active_anon 56559
  ...
    cpu: 7
              count: 332
              high:  378
              batch: 63
  vm stats threshold: 72
  node_unreclaimable:  0
  start_pfn:           1048576
  ...

查看总体内存信息meminfo:

~$ cat /proc/meminfo
MemTotal:       32791720 kB
MemFree:          930456 kB
MemAvailable:   12815656 kB
Buffers:         2036752 kB
Cached:          6727356 kB
SwapCached:          244 kB
Active:          5784032 kB
Inactive:        3470456 kB
Active(anon):     225796 kB
Inactive(anon):   263096 kB
...
Hugepagesize:       2048 kB
Hugetlb:               0 kB
DirectMap4k:    23929072 kB
DirectMap2M:     9529344 kB
DirectMap1G:           0 kB

虚拟内存信息

查看vmalloc映射信息vmallocinfo:

~$ sudo cat /proc/vmallocinfo
0xffffbc3d00000000-0xffffbc3d00005000   20480 irq_init_percpu_irqstack+0xcf/0x100 vmap
0xffffbc3d00005000-0xffffbc3d00007000    8192 acpi_os_map_iomem+0x17c/0x1b0 phys=0x000000008dbfe000 ioremap
...
0xffffbc3d0002c000-0xffffbc3d0002e000    8192 gen_pool_add_owner+0x42/0xb0 pages=1 vmalloc N0=1
0xffffbc3d0002e000-0xffffbc3d00030000    8192 bpf_prog_alloc_no_stats+0x4c/0xf0 pages=1 vmalloc N0=1
0xffffbc3d00030000-0xffffbc3d00035000   20480 _do_fork+0x76/0x370 pages=4 vmalloc N0=4
...
0xffffbc3d00065000-0xffffbc3d00068000   12288 pcpu_mem_zalloc+0x48/0x70 pages=2 vmalloc N0=2
0xffffbc3d00068000-0xffffbc3d0006c000   16384 n_tty_open+0x19/0xa0 pages=3 vmalloc N0=3

查看虚拟内存统计信息vmstat:

很多参数在内核编译时开启VM_EVENT_COUNTERS,因为这部分仅仅用于调试和统计。

$ cat /proc/vmstat

参考:
https://www.kernel.org/doc/Documentation/vm/transhuge.txt

实时虚拟内存命令vmstat:

vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监控。
是对系统的整体情况进行统计,无法进行某个进程的分析。

$ vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 26016976 972420 5206800    0    0     3     9   30    4  1  0 99  0  0
 0  0      0 26016716 972428 5206836    0    0     0     4  275  428  0  0 99  0  0
 0  0      0 26017284 972428 5206836    0    0     0     0  324  513  0  0 99  0  0
 0  0      0 26016992 972436 5206828    0    0     0     2  299  493  0  0 99  0  0
 0  0      0 26016512 972436 5206836    0    0     0     0  265  440  0  0 99  0  0

参考:https://www.cnblogs.com/ftl1012/p/vmstat.html

查看进程的vm分布pmap

pmap

pmap [pid]

$ pmap 13713
13713:   ./a.out
0000000000400000      4K r-x-- a.out
0000000000600000      4K r---- a.out
0000000000601000      4K rw--- a.out
0000000002315000    132K rw---   [ anon ]
00007f7e2ee73000   1948K r-x-- libc-2.27.so
00007f7e2f05a000   2048K ----- libc-2.27.so
00007f7e2f25a000     16K r---- libc-2.27.so
00007f7e2f25e000      8K rw--- libc-2.27.so
00007f7e2f260000     16K rw---   [ anon ]
00007f7e2f264000    164K r-x-- ld-2.27.so
00007f7e2f46b000      8K rw---   [ anon ]
00007f7e2f48d000      4K r---- ld-2.27.so
00007f7e2f48e000      4K rw--- ld-2.27.so
00007f7e2f48f000      4K rw---   [ anon ]
00007ffe47bad000    132K rw---   [ stack ]
00007ffe47bf8000     12K r----   [ anon ]
00007ffe47bfb000      4K r-x--   [ anon ]
ffffffffff600000      4K --x--   [ anon ]
 total             4516K

循环显示最后一行:

while true; do pmap -d  2173 | tail -1; sleep 2; done

pmap可以显示swap和匿名页等更多信息,使用pmap --help参看细节.

$ pmap -p 25991 -XX
25991:   /home/e0005055/wk/test/mm/a.out
         Address Perm   Offset Device    Inode Size KernelPageSize MMUPageSize  Rss Pss Shared_Clean Shared_Dirty Private_Clean Private_Dirty Referenced Anonymous LazyFree AnonHugePages ShmemPmdMapped FilePmdMapped Shared_Hugetlb Private_Hugetlb Swap SwapPss Locked THPeligible                   VmFlagsMapping
        00400000 r-xp 00000000 103:01 17050969    4              4           4    4   4            0            0             4             0          4         0        0             0              0             0              0               0    0       0      0           0    rd ex mr mw me dw sd  /home/e0005055/wk/test/mm/a.out
        00600000 r--p 00000000 103:01 17050969    4              4           4    4   4            0            0             0             4          4         4        0             0              0             0              0               0    0       0      0           0    rd mr mw me dw ac sd  /home/e0005055/wk/test/mm/a.out
        00601000 rw-p 00001000 103:01 17050969    4              4           4    4   4            0            0             0             4          4         4        0             0              0             0              0               0    0       0      0           0 rd wr mr mw me dw ac sd  /home/e0005055/wk/test/mm/a.out
        01c1e000 rw-p 00000000  00:00        0  132              4           4    4   4            0            0             0             4          4         4        0             0              0             0              0               0    0       0      0           0    rd wr mr mw me ac sd  [heap]
    7f5ec0f32000 r-xp 00000000 103:01 49681351 1948              4           4 1208  11         1208            0             0             0       1208         0        0             0              0             0              0               0    0       0      0           0       rd ex mr mw me sd  /lib/x86_64-linux-gnu/libc-2.27.so
    7f5ec1119000 ---p 001e7000 103:01 49681351 2048              4           4    0   0            0            0             0             0          0         0        0             0              0             0              0               0    0       0      0           0             mr mw me sd  /lib/x86_64-linux-gnu/libc-2.27.so
    7f5ec1319000 r--p 001e7000 103:01 49681351   16              4           4   16  16            0            0             0            16         16        16        0             0              0             0              0               0    0       0      0           0       rd mr mw me ac sd  /lib/x86_64-linux-gnu/libc-2.27.so
    7f5ec131d000 rw-p 001eb000 103:01 49681351    8              4           4    8   8            0            0             0             8          8         8        0             0              0             0              0               0    0       0      0           0    rd wr mr mw me ac sd  /lib/x86_64-linux-gnu/libc-2.27.so
    7f5ec131f000 rw-p 00000000  00:00        0   16              4           4   12  12            0            0             0            12         12        12        0             0              0             0              0               0    0       0      0           0    rd wr mr mw me ac sd  
    7f5ec1323000 r-xp 00000000 103:01 49681347  164              4           4  164   1          164            0             0             0        164         0        0             0              0             0              0               0    0       0      0           0    rd ex mr mw me dw sd  /lib/x86_64-linux-gnu/ld-2.27.so
    7f5ec152a000 rw-p 00000000  00:00        0    8              4           4    8   8            0            0             0             8          8         8        0             0              0             0              0               0    0       0      0           0    rd wr mr mw me ac sd  
    7f5ec154c000 r--p 00029000 103:01 49681347    4              4           4    4   4            0            0             0             4          4         4        0             0              0             0              0               0    0       0      0           0    rd mr mw me dw ac sd  /lib/x86_64-linux-gnu/ld-2.27.so
    7f5ec154d000 rw-p 0002a000 103:01 49681347    4              4           4    4   4            0            0             0             4          4         4        0             0              0             0              0               0    0       0      0           0 rd wr mr mw me dw ac sd  /lib/x86_64-linux-gnu/ld-2.27.so
    7f5ec154e000 rw-p 00000000  00:00        0    4              4           4    4   4            0            0             0             4          4         4        0             0              0             0              0               0    0       0      0           0    rd wr mr mw me ac sd  
    7ffd2b423000 rw-p 00000000  00:00        0  132              4           4   16  16            0            0             0            16         16        16        0             0              0             0              0               0    0       0      0           0    rd wr mr mw me gd ac  [stack]
    7ffd2b583000 r--p 00000000  00:00        0   12              4           4    0   0            0            0             0             0          0         0        0             0              0             0              0               0    0       0      0           0    rd mr pf io de dd sd  [vvar]
    7ffd2b586000 r-xp 00000000  00:00        0    4              4           4    4   0            4            0             0             0          4         0        0             0              0             0              0               0    0       0      0           0    rd ex mr mw me de sd  [vdso]
ffffffffff600000 --xp 00000000  00:00        0    4              4           4    0   0            0            0             0             0          0         0        0             0              0             0              0               0    0       0      0           0                      ex  [vsyscall]
                                               ==== ============== =========== ==== === ============ ============ ============= ============= ========== ========= ======== ============= ============== ============= ============== =============== ==== ======= ====== =========== 
                                               4516             72          72 1464 100         1376            0             4            84       1464        84        0             0              0             0              0               0    0       0      0           0 KB 

cat /proc/pid/maps

$ cat /proc/25991/maps
00400000-00401000 r-xp 00000000 103:01 17050969                          /home/e0005055/wk/test/mm/a.out
00600000-00601000 r--p 00000000 103:01 17050969                          /home/e0005055/wk/test/mm/a.out
00601000-00602000 rw-p 00001000 103:01 17050969                          /home/e0005055/wk/test/mm/a.out
01c1e000-01c3f000 rw-p 00000000 00:00 0                                  [heap]
7f5ec0f32000-7f5ec1119000 r-xp 00000000 103:01 49681351                  /lib/x86_64-linux-gnu/libc-2.27.so
7f5ec1119000-7f5ec1319000 ---p 001e7000 103:01 49681351                  /lib/x86_64-linux-gnu/libc-2.27.so
7f5ec1319000-7f5ec131d000 r--p 001e7000 103:01 49681351                  /lib/x86_64-linux-gnu/libc-2.27.so
7f5ec131d000-7f5ec131f000 rw-p 001eb000 103:01 49681351                  /lib/x86_64-linux-gnu/libc-2.27.so
7f5ec131f000-7f5ec1323000 rw-p 00000000 00:00 0 
7f5ec1323000-7f5ec134c000 r-xp 00000000 103:01 49681347                  /lib/x86_64-linux-gnu/ld-2.27.so
7f5ec152a000-7f5ec152c000 rw-p 00000000 00:00 0 
7f5ec154c000-7f5ec154d000 r--p 00029000 103:01 49681347                  /lib/x86_64-linux-gnu/ld-2.27.so
7f5ec154d000-7f5ec154e000 rw-p 0002a000 103:01 49681347                  /lib/x86_64-linux-gnu/ld-2.27.so
7f5ec154e000-7f5ec154f000 rw-p 00000000 00:00 0 
7ffd2b423000-7ffd2b444000 rw-p 00000000 00:00 0                          [stack]
7ffd2b583000-7ffd2b586000 r--p 00000000 00:00 0                          [vvar]
7ffd2b586000-7ffd2b587000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]

cat /proc/pid/smaps

详细描述每一个段的信息,和pmap命令差不多。

$ cat /proc/25991/smaps
00400000-00401000 r-xp 00000000 103:01 17050969                          /home/e0005055/wk/test/mm/a.out
Size:                  4 kB
KernelPageSize:        4 kB
MMUPageSize:           4 kB
Rss:                   4 kB
Pss:                   4 kB
Shared_Clean:          0 kB
...
THPeligible:		0
VmFlags: rd ex mr mw me dw sd 
00600000-00601000 r--p 00000000 103:01 17050969                          /home/e0005055/wk/test/mm/a.out
Size:                  4 kB
KernelPageSize:        4 kB
... ...

查看系统整体进程占用smem

smem是通过/proc/PID/smaps分析系统内存

$ smem
  PID User     Command                         Swap      USS      PSS      RSS 
25991 e0005055 /home/e0005055/wk/test/mm/a        0       88      100     1464 
17626 e0005055 script test.sh_tmp.log             0      172      212     2812 
 4398 e0005055 /usr/bin/dbus-daemon --conf        0      424      514     3840 
 5274 e0005055 /usr/lib/dconf/dconf-servic        0      688      766     5148 
 4296 e0005055 /usr/lib/x86_64-linux-gnu/x        0      680      769     5272 
 4384 e0005055 /usr/lib/at-spi2-core/at-sp        0      760      859     6280 
...

android 工具procmem/procrank

procrank是通过/proc/kpagemap分析,暂未实践。

overcommit与OOM

内存超量使用overcommit_memory

overcommit为超量使用,申请内存大小超过当前已申请(并非已分配)内存和swap的总和,仍然允许申请(并非分配),称为超量使用。
在meminfo中两个值:

~$ cat /proc/meminfo
...
CommitLimit:    18493008 kB
Committed_AS:    3567204 kB

CommitLimit为overcommit的阈值,申请的内存总数超过CommitLimit的话就算是overcommit。
Committed_AS 表示所有进程已经申请的内存总大小,如果超过CommitLimit就是已经发生overcommit。
CommitLimit既不是物理内存的大小,也不是free memory的大小,它是通过内核参数vm.overcommit_ratio或vm.overcommit_kbytes间接设置的,公式如下:
【CommitLimit = (Physical RAM * vm.overcommit_ratio / 100) + Swap】
overcommit_ratio是设定的超量使用比例,默认为50,可以通过overcommit_ratio查看:

~$ cat /proc/sys/vm/overcommit_ratio
50

超量使用可以通过以下方式查看:

~$ cat /proc/sys/vm/overcommit_memory
0

其中,0为默认值,允许超量使用,但是不能超过系统总内存。1为无限制超量使用,2为关闭超量使用。

sudo sh -c ‘echo 1 \> /proc/sys/vm/overconmit_memory’

其它配置方式:

  • 永久生效:
$ vim /etc/sysctl.conf
vm.overcommit_memory=1
$ sysctl -p
  • 临时修改:
$ sysctl  vm.overcommit_memory=1

或者:

$ sysctl  -w  vm.overcommit_memory=1

参考:
https://access.redhat.com/solutions/665023
http://linuxperf.com/?p=102

OOM

内存耗尽时,会根据当前进程的oom_score值来决定某一进程结束:
oom_score会加上oom_score_adj这个值,oom_score_adj的取值范围是-1000~1000,

$ cat /proc/898/oom_score
0
$ cat /proc/898/oom_score_adj
-999

oom_adj是调整进程优先级,序号越靠后,优先级越低,oom_score越大。范围【-17,16】默认为0,系统级进程为负值。
oom_adj是一个旧的接口参数,其功能类似oom_score_adj,保留时为了兼容,其实最后也是算oom_score_adj。
在这里插入图片描述

$ cat /proc/898/oom_adj
-16

OOM测试时,需要关闭swap分区,关闭overcommit:

sudo swapoff -a
sudo sh -c ‘echo 1 \> /proc/sys/vm/overconmit_memory’
git grep overcommit_memory

普通权限可以将oom_adj往后调整,但需要管理员权限才能往前调整:

$ cat /proc/18092/oom_adj
0
$ echo 13 >  /proc/18092/oom_adj
$ cat /proc/18092/oom_adj
12
$ echo 3 >  /proc/18092/oom_adj
-bash: echo: write error: Permission denied
$ sudo echo 3 >  /proc/18092/oom_adj
$ cat /proc/18092/oom_adj
2

/proc/sys/vm/panic_on_oom设定oom发生时,采取的策略。
当该参数等于0的时候,启动OOM killer回收内存。当该参数等于2的时候,强制kernel panic宕机。

$ cat /proc/sys/vm/panic_on_oom
0

/proc/sys/vm/oom_dump_tasks设定是否在oom时打印所有进程的内存信息,设置非0时会打印。

$ cat /proc/sys/vm/oom_dump_tasks
1

参考:https://blog.csdn.net/u011677209/article/details/52769225

内存泄漏检测工具

内存泄露通过长时间观察内存状态,占用持续上升。

valgrind

除内存泄露之外,可以检测多线程、缓存、堆栈等相关问题。

AddressSanitizer

Address Sanitizer是基于LLVM的的工具,已经内置在GCC4.8以上版本。使用时大概多出2倍的运行开销,属于比较快速的工具。
Address Sanitizer替换了malloc和free的实现。根据内存分配和释放操作,将不可访问区域标记为”off-limits“,当访问到这些标记内存区域时,报告异常。
Address Sanitizer可以用来检测如下内存使用错误:

内存释放后又被使用;
内存重复释放;
释放未申请的内存;
使用栈内存作为函数返回值;
使用了超出作用域的栈内存;
内存越界访问;

需要在程序编译时使用 -fsanitize=address、-fsanitize=leaks,-fno-omit-frame-pointer用于额外的堆栈信息。之后再运行,出现问题时会报错。

静态代码检测工具cppcheck

cppcheck是一个C/C++静态检查工具。协助侦测代码级别的问题,比如数组越界、内存申请未释放、文件打开未关闭等。
大部分IDE都有用于静态检测的插件,比如SourceInsight\Eclipse\VS Code , 可以在互联网搜索相关信息。

内核泄露检测kmemleak

有时候内存泄露并不是应用造成的,而是依赖的对应内核模组产生的。kmemleak是Linux内核自带的检测工具,不过使用该功能需要在内核编译时需要打开kmemleaks选项,重新编译内核。

GNU C库中的内存检测工具mtrace

mtrace是GNU扩展函数,mtrace为内存分配函数(malloc, realloc, memalign, free)安装hook函数。
使用mtrace需要在代码里添加mtrace函数重新编译运行,在运行停止之后会打印出尚未释放的内存信息,然后用mtrace分析log,找到对应的函数。之后查看代码,分析其调用信息修改。

内存分析一般步骤

工程调试内存泄漏问题一般步骤:

  1. meminfo, free 多点采样
    使用多点采样,确认是否有内存泄漏。

  2. 定位程序
    通过smem等方式,检查用户空间,找到可疑的应用程序

  3. 检查内核空间
    通过slab等信息判断内核是否存在泄露,通过kmemleak分析内核泄露信息。

  4. 通过buddy、slab、meminfo等系统信息来辅助分析。

page cache

缓存和回收

free 命令中,buff是指文件IO时的缓存,cache是上层文件系统的缓存。
在这里插入图片描述
不带pagecached的IO为direct IO。 可以在用户态根据业务特点做cached,在某些场合上会在应用层来建立对应的访问逻辑。
类似于CPU跳过cache,直接访问mem;

匿名页和文件背景页

  • 文件背景页:
  • 在内存的缓存中,具有文件属性的缓存称为file_page,可以回收。比如代码段,映射文件等。
  • 匿名页:
    堆栈变量类的数据为anon page,匿名页,不可回收。

swap

在内核配置CONFIG_SWAP,支持匿名页swap。不配置,普通文件swap依然支持;
SWAP分区,对应windows的虚拟内存文件pagefile.system。

页面回收和LRU

局部性原理:最近活跃的就是将来活跃的,最近不活跃的,以后也不活跃。
包括时间局部性,空间局部性。
LRU:Least Recently Used最近最少使用,是一种常用的页面置换算法。

问题

swap匿名页可以理解,是将数据交换到磁盘上的swap区域。
但是普通文件swap,究竟交换的是什么?比如一个so文件,swap到swap分区,和直接与库文件原先的位置来加载有啥区别?
答案:普通文件不需要swap,文件页本身就是可以回收的,不需要放到匿名页。swap只是针对匿名页,原本不可回收的、没有任何文件背景的数据。

嵌入式设备和zRAM:

嵌入式设备,一般不用swap,不使能swap,因为:
1.嵌入式磁盘速度很慢;
2.FLASH读写寿命有限;
zRAM的功能就是将RAM划分一部分区域,将RAM中数据压缩放入该区域来swap。这就实现了用CPU算力来换取空间。

#内核使能swap
echo $((48*1024*1024)) > /sys/block/zram0/disksize  
打开swap分区:
swapon –p 10 /dev/zram0 
cat /proc/swaps

swapoff –a 不能关掉文件背景页面。

脏页写回

脏页回写是由pdfulsh执行的。其运行周期dirty_writeback_centisecs,单位厘秒:

$ cat /proc/sys/vm/dirty_writeback_centisecs
500

脏页回写有两个机制:

超过时间周期触发回收

  • dirty_expire_centisecs
    既定时间周期执行/proc/sys/vm/dirty_expire_centisecs 周期
    单位厘秒(默认值3000厘秒:3000*10毫秒,3000/100秒)
$ cat /proc/sys/vm/dirty_expire_centisecs 
3000

超过空间比值触发回收

  • dirty_background_ratio
    脏页所占比例到达既定值/proc/sys/vm/dirty_background_ratio
    脏数据所占内存 / (MemFree + Cached - Mapped ) > dirty_background_ratio,默认10%
$ cat /proc/sys/vm/dirty_background_ratio
10

当dirty_expire_centisecss设置较小,刷新频率就会增加,这样就会使得脏数据所占总内存的比例不会达到dirty_background_ratio,从而使得dirty_background_ratio参数没有什么作用。
相反,如果dirty_background_ratio参数设置很小同时dirty_expire_centisecs设置较大,dirty_expire_centisecss可能也用不上。

  • dirty_ratio
    当系统大量触发IO,硬件IO速度达不到缓存的速度,导致脏页比例超过该值时,所有IO将被停止,直到当前数据回写完成。默认为20%。
$ cat /proc/sys/vm/dirty_ratio 
20

假如某个进程在不停写数据,当写入大小触发dirty_background_ratio_10%时,脏页开始写入磁盘,写入数据大小触发dirty_ratio_20%时(磁盘IO速度远比写内存慢),如果继续写,会被内核阻塞,等脏页部分被写入磁盘,释放pagecached后,进程才能继续写入内存;
参考:
https://www.cnblogs.com/ywcz060/p/5589926.html
https://blog.csdn.net/u010039418/article/details/107500892

swappiness空间回收

内存回收,是通过kswap进行的,涉及三个水位值,min\low\high:

:~$ sudo cat /proc/zoneinfo
Node 0, zone      DMA
...
Node 0, zone   Normal
  pages free     201343
        min      15777
        low      23415
        high     31053
        spanned  7790592

当内存水位低于low时开始回收,直到水位达到high停止。当水位低于min时,直接阻塞应用,在进程上下文直接回收。

默认值60,最大值100.Swappiness越大,越优先回收匿名页;
即使Swappiness设置为0,优先回收文件背景页,以使达到最低水位;假使达不到,还是会回收匿名页;

cgroup中使用内存

./swapoff –a

echo 1 \> /proc/sys/vm/overcommit_memory //

cd /sys/fs/cgroup/memory

mkdir A

cd A

sudo echo \$(100\*1024\*1024) \> memory.limit_in_bytes //限制最大内存100M

//a.out放到A cgroup执行;

sudo cgexec –g memory:A ./a.out

swap主要是解决内存不足的问题。
目前, Hadoop集群,kubernetes等都会关闭swap。首先是swap交换引起IO和内存的性能问题。另外,开启swap后通过cgroups设置的内存上限就会失效。
另外,对于cgroup而言,设置swappiness=0,该group的swap回收会被关闭;但是全局的swap还是可以回收;

Q&A

Q: swap只针对匿名页,不会对文件页进行交换。比如lib.so等,没有意义。
A:是的,文件页是直接回收,匿名页才会被交换到swap分区。

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐