프로세스에서 사용하는 'Res' 메모리가 일정한데 사용 가능한 물리적 메모리가 어떻게 줄어들 수 있나요?

프로세스에서 사용하는 'Res' 메모리가 일정한데 사용 가능한 물리적 메모리가 어떻게 줄어들 수 있나요?

설명할 수 없는 다음과 같은 동작이 관찰됩니다. 서버에서 보고하는 사용 가능한 물리적 메모리의 양은 증가하는 반면, 메모리를 가장 많이 사용하는 프로세스(웹 서버 프로세스)에서 보고하는 'Res' 메모리는 거의 균일합니다.

내가 주로 이해하고 싶은 것은 프로세스에 의해 보고된 상주 메모리가 일정한 동안 물리적 메모리 사용이 증가하는 것이 어떻게 가능하다는 것입니다. 특히 많은 로드를 생성하지 않고 관찰 가능한 동작을 유발하기 위해 이러한 프로세스 내부에서 무슨 일이 일어날 수 있습니까?

즉, 처음에는 '상주'로 보고되었지만 실제로 물리적 메모리를 점유하지 않은 '메모리'가 여전히 '상주'로 보고되지만 지금은 변경되는 것과 같은 프로세스 내에서 일어날 수 있는 일입니다. 실제로 물리적 메모리도 차지합니까?

예: 메모리가 2GB인 가상 서버가 있습니다. top/ free[1] 에서 보고한 바와 같이 어제 12시에는 약 800MB(40%)가 사용되었습니다 . 대부분은 몇 가지 프로세스에서 사용되며, 총 1.2GB의 상주 메모리가 사용된 것으로 보고되었습니다[2].

그런 다음 몇 가지 테스트(이 프로세스에서 제공하는 대량의 HTTP 요청 수행)를 시작하여 실제 메모리 사용량을 1.2GB(60%)로 늘리고 프로세스에서 사용하는 상주 메모리를 3.2GB로 늘렸습니다. 그 후에는 서버를 전혀 건드리지 않았으며 공개적으로 사용할 수 없습니다. 이후 로드는 0.03 미만이었습니다.

그럼에도 불구하고, 프로세스에 의해 보고된 상주 메모리는 3.2GB로 균일했지만, 물리적 메모리 사용량은 서서히 증가하여 어느 시점에서 90%(1.8GB)를 초과하여 플래그가 발생했습니다. 이러한 웹 서버 프로세스 내에서는 그 당시 아무 일도 일어나지 않았으며(부하로 입증됨) 실행 중인 특별한 작업도 없습니다.

위의 시나리오 그래프를 볼 수 있습니다여기. 위쪽 그래프가 보여주는 것은 정확히 top/ free사용 가능한 물리적 메모리로 보고되는 것입니다. 아래쪽 그래프에 표시되는 내용은 정확히 top'Res' 열에 보고된 내용입니다. 표시된 영역은 Ruby총 6개의 프로세스입니다.

[1] 일반적으로 이러한 서버에서는 모든 메모리가 '사용됨'으로 표시되고 모든 여유 메모리는 캐시에 사용됩니다. 내 말은 마지막 바이트까지라는 뜻입니다. top및 안의 다른 모든 숫자 free는 0입니다.

[2] 여러 프로세스에서 보고된 상주 메모리의 합이 사용된 물리적 메모리를 초과할 수 있다는 것을 알고 있지만, 모르는 것 같습니다.모두이런 일이 일어날 수 있는 방법 중.

답변1

RSS가 있기 때문에 이런 일이 발생합니다~ 아니다해당 프로그램에서 사용되는 메모리의 양을 알려주는 신뢰할 수 있는 값입니다. 해당 프로그램이 얼마나 많은 상주 메모리를 매핑하는지에 대한 권위 있는 값입니다. 그리고 차이점이 있습니다.

RSS는 기껏해야 사용 중인 메모리 양에 대한 힌트로만 사용할 수 있습니다.

커널에는 메모리를 절약하기 위한 많은 트릭이 있습니다. 프로세스는 많은 메모리를 공유할 수 있으며, 특히 분기되는 프로세스는 더욱 그렇습니다.

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

상단에는 14610520KB의 여유 메모리가 표시됩니다.

프로그램을 실행해 보겠습니다.

$ python trick_rss.py & top -bn1 -u matthew
[2] 3465
top - 21:04:54 up 13 min,  1 user,  load average: 0.05, 0.07, 0.08
Tasks: 415 total,   1 running, 414 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.7 us,  0.3 sy,  0.0 ni, 98.8 id,  0.2 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:  16124248 total,  1832040 used, 14292208 free,    78320 buffers
KiB Swap:  8069116 total,        0 used,  8069116 free,   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

14292208KB의 여유 공간이 있습니다. 약 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 & sleep 5; free -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

답변2

Ruby(또는 기타) 프로세스 간에 공유되는 메모리 양이 감소함에 따라 사용되는 실제 메모리 양이 늘어날 수 있습니다. 그러나 귀하의 경우에는 시스템이 유휴 상태이므로 어떠한 변경도 기대할 수 없습니다. 아마도 Ruby 가비지 수집기로 인해 공유가 줄어들었을 수 있습니다.http://www.rubyenterpriseedition.com/faq.html말한다:

따라서 가비지 수집 주기로 인해 모든 개체가 기록됩니다(또는 운영 체제 전문 용어로 개체의 메모리 페이지가 더러워집니다). OS는 해당 메모리를 모두 복사하므로 쓰기 중 복사 효과가 무효화됩니다.

이 기간 동안 공유된 메모리 양은 어떻게 되나요?

관련 정보