我主要想了解的是:当进程报告的驻留内存不变时,如何增加物理内存的使用率.在这些过程中可能发生什么导致可观察到的行为,特别是在没有产生太多负载的情况下?
换句话说:在一个进程内部会发生什么,以至于“内存”首先被报告为“常驻”,但实际上并没有以这样的方式占用任何物理内存变化,以至于它仍被报告为“常驻”,但现在实际上还占据了物理记忆?
例:
我有一个2GB内存的虚拟服务器.昨天中午12点,大约800MB(40%)正在使用,正如top / free [1]报道的那样.大多数进程都使用了大多数进程,它们共同报告了大约1.2GB的常驻内存[2].
然后我开始了一些测试(执行这些进程提供的大量HTTP请求),这使得物理内存使用量增加到1.2GB(60%),并将进程使用的驻留内存增加到3.2GB.在那之后,我根本没有碰到服务器而且它没有公开可用:负载是< 0.03之后. 尽管如此,虽然进程报告的驻留内存平均为3.2GB,但物理内存使用量缓慢增加,并且在某些时候超过了90%(1.8GB),导致标记被提升.在这些Web服务器进程中,当时没有任何事情发生(由负载证明)并且没有任何特殊作业在运行. 可以看到上面的场景图表here.上图显示的是自由物理内存的顶级/免费报告.下方图表显示的是“Res”列中的热门报告.请注意,标记为Ruby的区域总共有6个进程.
[1]通常在这些服务器上,所有内存都标记为“已使用”,所有可用内存都用于缓存.我的意思是:直到最后一个字节. top和free中的所有其他数字均为0.
[2]据我所知,几个进程报告的驻留内存总和可能超过使用的物理内存,但我不认为我知道这种情况发生的所有方式.
解决方法
内核有很多技巧可以节省内存.进程可能共享大量内存,尤其是fork的进程.
如果你有一个分配100M内存的父级,那么产生一个孩子这两个进程将共享该内存区域,父级和子级都将声称RSS值>> 100M,因为它们都映射到同一个记忆区域.从技术上讲,这是正确的,父进程的RSS是> = 100M,因为进程已经映射了多少内存,并且子进程也有RSS> = 100M,因为该进程也有很多映射,只是碰巧两个进程共享(大部分)相同的映射.
你可以用一些简单的python来证明这一点.
#!/usr/bin/python import os,sys,signal HOG = 'A' * 104857600 ## 100 MB try: for i in range(100): pid = os.fork() if pid: continue else: break signal.pause() except KeyboardInterrupt: sys.exit(0)
该程序创建一个100M的内存区域,并用’A’填充它.然后它产生100个孩子(总共101个进程)然后等待ctrl-c.
这是之前的情景.
$top -bn1 -u matthew top - 21:03:04 up 11 min,1 user,load average: 0.04,0.08,0.09 Tasks: 212 total,1 running,211 sleeping,0 stopped,0 zombie %cpu(s): 0.7 us,0.3 sy,0.0 ni,98.7 id,0.2 wa,0.0 hi,0.0 si,0.0 st KiB Mem: 16124248 total,1513728 used,14610520 free,78268 buffers KiB Swap: 8069116 total,0 used,8069116 free,578148 cached PID USER PR NI VIRT RES SHR S %cpu %MEM TIME+ COMMAND 1837 matthew 20 0 767916 5072 3400 S 0.0 0.0 0:00.06 gnome-keyr+ 1880 matthew 20 0 13920 608 468 S 0.0 0.0 0:00.00 dbus-launch 1949 matthew 20 0 307180 2804 2312 S 0.0 0.0 0:00.01 gvfsd 2051 matthew 20 0 337684 2908 2436 S 0.0 0.0 0:00.00 at-spi-bus+ 2059 matthew 20 0 127260 2920 2360 S 0.0 0.0 0:00.05 at-spi2-re+ 2082 matthew 9 -11 486316 7044 4376 S 0.0 0.0 0:00.09 pulseaudio 2121 matthew 20 0 317660 2952 2324 S 0.0 0.0 0:00.00 gvfs-gphot+ 2132 matthew 20 0 1440732 105732 30156 S 0.0 0.7 0:09.64 gnome-shell 2145 matthew 20 0 513076 3996 3064 S 0.0 0.0 0:00.00 gsd-printer 2160 matthew 20 0 313300 3488 2940 S 0.0 0.0 0:00.00 ibus-dconf 2172 matthew 20 0 775428 14000 10348 S 0.0 0.1 0:00.05 gnome-shel+ 2182 matthew 20 0 319120 7120 5444 S 0.0 0.0 0:00.07 mission-co+ 2196 matthew 20 0 232848 2708 2164 S 0.0 0.0 0:00.00 gvfsd-Meta+ 2206 matthew 20 0 408000 11828 8084 S 0.0 0.1 0:00.06 abrt-applet 2209 matthew 20 0 761072 15120 10680 S 0.0 0.1 0:00.13 nm-applet 2216 matthew 20 0 873088 14956 10600 S 0.0 0.1 0:00.09 evolution-+ 2224 matthew 20 0 1357640 29248 14052 S 0.0 0.2 0:00.26 evolution-+ 2403 matthew 20 0 295036 6680 3876 S 0.0 0.0 0:00.01 telepathy-+ 2475 matthew 20 0 380916 2756 2264 S 0.0 0.0 0:00.00 gvfsd-burn 2486 matthew 20 0 8460 736 608 S 0.0 0.0 0:00.00 gnome-pty-+ 2617 matthew 20 0 116412 3068 1596 S 0.0 0.0 0:00.04 bash 2888 matthew 20 0 457196 9868 5164 S 0.0 0.1 0:00.05 telepathy-+ 3347 matthew 20 0 123648 1400 1020 R 0.0 0.0 0:00.00 top
顶部显示14610520 KB可用内存.
让我们运行我们的程序:
$python trick_RSS.py & top -bn1 -u matthew [2] 3465 top - 21:04:54 up 13 min,load average: 0.05,0.07,0.08 Tasks: 415 total,414 sleeping,98.8 id,1832040 used,14292208 free,78320 buffers KiB Swap: 8069116 total,578144 cached PID USER PR NI VIRT RES SHR S %cpu %MEM TIME+ COMMAND 3465 matthew 20 0 227652 106676 1792 S 31.7 0.7 0:00.05 python 2483 matthew 20 0 641568 18736 11656 S 6.3 0.1 0:01.26 gnome-term+ 1837 matthew 20 0 767916 5072 3400 S 0.0 0.0 0:00.06 gnome-keyr+ 1880 matthew 20 0 13920 608 468 S 0.0 0.0 0:00.00 dbus-launch 1949 matthew 20 0 307180 2804 2312 S 0.0 0.0 0:00.01 gvfsd 2051 matthew 20 0 337684 2908 2436 S 0.0 0.0 0:00.00 at-spi-bus+ 2059 matthew 20 0 127260 2920 2360 S 0.0 0.0 0:00.05 at-spi2-re+ 2082 matthew 9 -11 486316 7044 4376 S 0.0 0.0 0:00.09 pulseaudio 2121 matthew 20 0 317660 2952 2324 S 0.0 0.0 0:00.00 gvfs-gphot+ 2136 matthew 20 0 178692 2588 1788 S 0.0 0.0 0:00.00 dconf-serv+ 2145 matthew 20 0 513076 3996 3064 S 0.0 0.0 0:00.00 gsd-printer 2160 matthew 20 0 313300 3488 2940 S 0.0 0.0 0:00.00 ibus-dconf 2172 matthew 20 0 775428 14000 10348 S 0.0 0.1 0:00.05 gnome-shel+ 2182 matthew 20 0 319120 7120 5444 S 0.0 0.0 0:00.07 mission-co+ 2196 matthew 20 0 232848 2708 2164 S 0.0 0.0 0:00.00 gvfsd-Meta+ 2206 matthew 20 0 408000 11828 8084 S 0.0 0.1 0:00.06 abrt-applet 2209 matthew 20 0 761072 15120 10680 S 0.0 0.1 0:00.14 nm-applet 2216 matthew 20 0 873088 14956 10600 S 0.0 0.1 0:00.10 evolution-+ 2224 matthew 20 0 1357640 29248 14052 S 0.0 0.2 0:00.26 evolution-+ 2403 matthew 20 0 295036 6680 3876 S 0.0 0.0 0:00.01 telepathy-+ 2475 matthew 20 0 380916 2756 2264 S 0.0 0.0 0:00.00 gvfsd-burn 2487 matthew 20 0 116544 3316 1716 S 0.0 0.0 0:00.09 bash 2804 matthew 20 0 1239196 275576 41432 S 0.0 1.7 0:25.54 firefox 2890 matthew 20 0 436688 15932 7288 S 0.0 0.1 0:00.05 telepathy-+ 3360 matthew 20 0 227652 106680 1792 S 0.0 0.7 0:00.05 python 3366 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3368 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3370 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3372 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3374 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3376 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3378 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3380 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3382 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3384 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3386 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3388 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3390 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3392 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3394 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3396 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3398 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3400 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3402 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3404 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3406 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3408 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3410 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3412 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3414 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3416 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3418 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3420 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3422 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3424 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3426 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3428 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3430 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3432 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3434 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3436 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3438 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3440 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3442 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3444 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3446 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3448 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3450 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3452 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3454 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3456 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3458 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3460 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3462 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3464 matthew 20 0 227652 105096 208 S 0.0 0.7 0:00.00 python 3467 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3469 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3471 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3473 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3475 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3477 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3479 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3481 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3483 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3485 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3487 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3489 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3491 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3493 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3495 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3497 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3499 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3501 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3503 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3505 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3507 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3509 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3511 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3513 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3515 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3517 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3519 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3521 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3523 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3525 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3527 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3529 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3531 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3533 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3535 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3537 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3539 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3541 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3543 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3545 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3547 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3549 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3551 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3553 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3555 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3557 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3559 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3561 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3563 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python 3565 matthew 20 0 227652 105092 208 S 0.0 0.7 0:00.00 python
我有14292208 Kb免费.大约300M的内存已用完.但是,如果我按照RSS告诉我的方式,我实际上使用了10GB的内存!
最后,如果您查看进程映射,您可以看到虚拟内存地址彼此相同.
$pmap -x 3561 ... 00007f05da5e8000 102404 102404 102404 rw--- [ anon ] ... $pmap -x 3565 ... 00007f05da5e8000 102404 102404 102404 rw--- [ anon ] ...
懒惰复制
此C程序演示了延迟复制,在这种情况下,所有进程都映射到相同的内存区域,但子进程已覆盖内容.在后台,内核将这些页面重新映射到实际内存中的不同位置,但显示相同的虚拟地址空间.
现在,每个实例确实占用内存,但RSS值保持不变.
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <string.h> int main() { int i; char c=65; pid_t pid; signal(SIGCHLD,SIG_IGN); /* Allocate some memory */ char *hog = malloc(104857600); memset(hog,c,104857600); for (i=1; i < 4; i++) { if (fork()) continue; memset(hog,c+i,104857600); break; } sleep(3); printf("Pid %d shows HOG[1048576] saying %c\n",getpid(),hog[1048576]); pause(); }
使用gcc -o trick_RSS trick_RSS.c编译.并使用free -m运行; ./trick_RSS&睡5;免费-m.
得到以下结果;
$free -m; ./trick_RSS & sleep 5; free -m total used free shared buffers cached Mem: 15746 2477 13268 0 79 589 -/+ buffers/cache: 1808 13938 Swap: 7879 0 7879 [3] 4422 Pid 4422 shows HOG[1048576] saying A Pid 4424 shows HOG[1048576] saying B Pid 4425 shows HOG[1048576] saying C Pid 4426 shows HOG[1048576] saying D total used free shared buffers cached Mem: 15746 2878 12867 0 79 589 -/+ buffers/cache: 2209 13536 Swap: 7879 0 7879