사용 가능한 메모리가 기가바이트인데 왜 atop
20,000페이지(80MB 이상) 이상을 교환한다고 표시됩니까 ?
나는 이것에 대한 성능 문제를 발견하지 못했습니다. 저는 이 기회를 통해 지식을 늘리고 싶었습니다 :-).
atop
10초마다 새로 고쳐집니다. 새로 고칠 때마다 마지막 새로 고침 이후의 활동이 표시됩니다.
MEM | tot 7.7G | free 3.7G | cache 608.3M | buff 19.1M | slab 264.6M |
SWP | tot 2.0G | free 1.4G | | vmcom 13.4G | vmlim 5.8G |
PAG | scan 167264 | steal 109112 | stall 0 | swin 0 | swout 23834 |
"swout" is non-zero and coloured in red ^
커널 메모리 정보:
$ head -n 5 /proc/meminfo
MemTotal: 8042664 kB
MemFree: 3563088 kB
MemAvailable: 3922092 kB
Buffers: 20484 kB
Cached: 775308 kB
커널 버전:
$ uname -r
5.0.16-200.fc29.x86_64
이것이 영향을 받을지는 불분명합니다
vm.swappiness
. 이 설정은 캐시 제거와 스와핑의 균형을 유지합니다. 그러나 많은무료기억, 그렇다면 애초에 기억을 되찾아야 하는 이유는 무엇입니까?보시다시피 이것은 작은 시스템입니다. NUMA를 사용하지 않습니다. 체크인한 결과
/proc/zoneinfo
"Node 0" 노드가 하나만 있는 것으로 나타났습니다. 그래서 이것은 아니다NUMA로 인해 발생함.관련 질문과 답변에는 "기회적 스와핑", "시스템이 할 일이 없을 때", "나중에 메모리 부족이 발생하는 경우" 등과 같은 아이디어가 언급되어 있습니다. 나는 이러한 아이디어가 커널 문서와 모순되기 때문에 신뢰할 수 없다고 생각합니다. 바라보다 Linux는 "기회적 교환"을 수행합니까, 아니면 신화입니까?
이 기능을 사용할 때 RAM 사용량에는 설정된 제한이 없습니다
systemd.resources
. 즉systemd
, 모든 장치의 RAM 사용 제한이 "무제한"으로 설정되어 있는 것 같습니다 .$ systemctl show '*' | \ grep -E '(Memory|Swap).*(Max|Limit|High)' | \ grep -v infinity $
편집: 나는 이것이 투명한 거대한 페이지와 관련이 있다고 생각합니다. 가상 머신은 게스트 메모리를 효율적으로 할당하기 위해 투명한 hugepage를 사용하는 것으로 나타났습니다. 거대한 페이지를 사용하는 유일한 사용자 프로그램입니다.내 시스템에서.
비슷한 질문이 있습니다:사용 가능한 메모리가 Pages_high 워터마크보다 훨씬 높으면 kswapd를 활성화할 수 있습니까?모든 애플리케이션에 대해 대형 페이지를 지원하는 RHEL 6에 대해 묻고 있습니다.
이 결과를 재현하는 방법을 잘 모르겠습니다.
이는 가상 머신을 시작할 때 발생합니다. libvirt를 사용하여 가상 머신을 실행합니다. 기본적으로 VM 디스크 읽기는 호스트 페이지 캐시를 사용하여 캐시됩니다. (캐시 모드: "하이퍼바이저 기본값"은 "쓰기 저장"을 의미합니다).
가상 머신, FADVISE_DONTNEED
이미지 파일을 중지하고 다시 시도했습니다. 그러나 같은 일은 일어나지 않았습니다.
그런 다음 다른 가상 머신으로 다시 시도했는데 이 문제가 잠시 동안 발생했습니다. 나는 그것을 잡았다 vmstat
. 나는 "swout"이 다른, 더 높은 숫자를 나타내는 것이라고 생각했지만 atop
그것을 잡지 못했습니다.
$ vmstat 10
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 770168 5034300 28024 936256 0 2 21 86 60 101 22 9 68 1 0
0 0 770168 5033852 28048 935904 0 0 0 8 372 633 1 1 97 0 0
1 0 770168 4974048 28252 948152 3 0 1137 194 1859 2559 11 7 79 3 0
0 1 770168 4557968 28308 1037512 0 0 8974 45 3595 6218 16 6 57 21 0
6 3 770168 4317800 28324 1111408 0 0 7200 609 6820 6793 12 5 38 44 0
0 4 770168 4125100 28348 1182624 0 0 6900 269 5054 3674 74 3 8 15 0
0 5 770168 3898200 27840 1259768 2 0 9421 630 4694 5465 11 6 11 71 0
1 3 770168 3760316 27672 1300540 0 0 9294 897 3308 4135 5 4 28 63 0
0 1 770168 3531332 27032 1356236 0 0 10532 155 3140 4949 8 5 63 25 0
0 0 783772 3381556 27032 1320296 0 1390 7320 4210 4450 5112 17 5 43 35 0
0 0 783772 3446284 27056 1335116 0 0 239 441 995 1782 4 2 92 2 0
0 0 783772 3459688 27076 1335372 0 0 3 410 728 1037 2 2 95 1 0
systemd
또한 libvirt가 우회 하고 실수로 자체 스왑하는 경우를 대비하여 VM의 cgroup 메모리 제한도 확인했습니다 .
$ cd /sys/fs/cgroup/memory/machine.slice/machine-qemu\x2d5\x2ddebian9.scope
$ find -type d # there were no sub-directories here
$ grep -H . *limit_in_bytes
memory.kmem.limit_in_bytes:9223372036854771712
memory.kmem.tcp.limit_in_bytes:9223372036854771712
memory.limit_in_bytes:9223372036854771712
memory.memsw.limit_in_bytes:9223372036854771712
memory.soft_limit_in_bytes:9223372036854771712
$ cd ../..
$ find -name "*limit_in_bytes" -exec grep -H -v 9223372036854771712 \{\} \;
$
답변1
나는 비슷한 문제에 대해 생각하고 있었습니다. kswapd 및 영역 워터마크에 대한 내 게시물을 보셨을 겁니다. 제 경우(그리고 아마도 귀하의 경우에도 마찬가지)의 대답은 메모리 조각화였습니다.
메모리가 충분히 단편화되면 고차 할당이 실패하여 (다른 많은 요인에 따라) 직접 회수가 발생하거나 kswapd가 깨어나 영역 회수/압축을 시도합니다. 내 게시물에서 몇 가지 추가 세부정보를 확인할 수 있습니다.
이와 같은 문제를 다룰 때 간과될 수 있는 또 다른 사항은 메모리입니다.분할. 즉, 아마도 메모리가 충분할 것입니다.포괄적인(충분한 연속 블록을 포함할 수도 있습니다.) 그러나 DMA32로 제한될 수 있습니다(64비트 아키텍처를 사용하는 경우). 어떤 사람들은 DMA32를 "작다"고 무시하는 경향이 있지만(아마도 그들이 32비트 생각에 익숙하기 때문일 것입니다), 4GB는 실제로 "작다"는 것이 아닙니다.
귀하의 사건에서 무슨 일이 일어났는지 판단하는 방법에는 두 가지가 있습니다. 하나는 통계를 분석하는 것입니다. /proc/buddyinfo, /proc/zoneinfo, /proc/vmstat 등의 주기적 스냅샷을 찍도록 작업을 설정하고 현재 보고 있는 내용을 이해하려고 노력할 수 있습니다.
작동하게 되면 또 다른 접근 방식이 더 간단하고 안정적입니다. 스왑 이벤트로 이어지는 코드 경로를 캡처해야 하며 커널 계측 추적점을 사용하여 이 작업을 수행할 수 있습니다(특히 vmscan 이벤트가 많이 있음).
그러나 낮은 수준의 계측기가 항상 원래대로 작동하는 것은 아니기 때문에 이를 작동시키는 것이 어려울 수 있습니다. 내 경우에는 ftrace 인프라를 설정하는 데 시간이 좀 걸렸지만 결국 우리에게 필요한 function_graph 프로브가 어떤 이유로 작동하지 않는다는 사실을 발견했습니다. 우리가 시도한 다음 도구는 perf였지만 첫 번째 시도에서도 작동하지 않았습니다. 그러나 마침내 관심 있는 이벤트를 캡처하면 그 어떤 글로벌 카운터보다 더 빠르게 답변을 얻을 수 있습니다.
감사합니다, 니콜라