이 견해는 여러 실제 사례에서 매우 오해의 소지가 있습니다.
커널은 이제 MemAvailable
현장 에서 사용 가능한 메모리에 대한 추정치를 제공 합니다. 이 값은와 크게 다릅니다 MemFree + Cached
.
/ proc / meminfo : 사용 가능한 예상 메모리 제공 [커널 변경 설명, 2014]
많은로드 밸런싱 및 워크로드 배치 프로그램은 사용 가능한 메모리 양을 추정하기 위해 / proc / meminfo를 확인합니다. 그들은 일반적으로 10 년 전에는 괜찮은 "무료"와 "캐시 된"을 합쳐서이 작업을 수행하지만 오늘날에는 틀린 것이 거의 보장됩니다.
캐시에는 공유 메모리 세그먼트, tmpfs 및 ramfs와 같이 페이지 캐시로 사용 가능하지 않은 메모리가 포함되어 있으며 재생 가능한 슬랩 메모리는 포함되어 있지 않기 때문에 잘못되었습니다. 많은 파일.
현재 시스템을 스왑으로 푸시하지 않고 새로운 워크로드에 사용할 수있는 메모리 양은 MemFree, Active (파일), Inactive (파일) 및 SReclaimable 및 /에서 "낮은"워터 마크로 추정 할 수 있습니다. proc / zoneinfo. 그러나 이것은 미래에 변경 될 수 있으며 사용자 공간은 실제로 사용 가능한 메모리 양에 대한 추정치를 커널 내부에서 알 필요가 없습니다. / proc / meminfo에 이러한 견적을 제공하는 것이 더 편리합니다. 앞으로 상황이 바뀌면 한 곳에서만 변경하면됩니다.
...
Documentation / filesystems / proc.txt :
...
MemAvailable : 스왑없이 새 응용 프로그램을 시작하는 데 사용할 수있는 메모리의 양입니다. MemFree, SReclaimable, 파일 LRU 목록의 크기 및 각 영역의 낮은 워터 마크에서 계산됩니다. 이 추정치는 시스템이 제대로 작동하기 위해 일부 페이지 캐시가 필요하며 항목이 사용 중이기 때문에 모든 재생 가능한 슬래브를 재생하는 것이 아니라는 점을 고려합니다. 이러한 요소의 영향은 시스템마다 다릅니다.
1. 가능한 세부 사항
위에서 말했듯이 tmpfs 및 기타 Shmem
메모리는 해제 할 수 없으며 스왑으로 만 이동됩니다. 이 스왑 가능한 메모리 를 포함하여 Cached
in /proc/meminfo
은 매우 오도 될 수 있습니다 Shmem
. tmpfs에 파일이 너무 많으면 많은 메모리를 차지할 수 있습니다 :-). Shmem
또한 일부 그래픽 메모리 할당 을 포함 할 수 있으며 이는 매우 클 수 있습니다.
MemAvailable
고의로 스왑 가능한 메모리는 포함되지 않습니다. 스와핑을 너무 많이하면 지연 될 수 있습니다. 스왑 공간없이 실행하거나 비교적 제한된 양만 허용했을 수도 있습니다.
MemAvailable
작동 방식 을 다시 확인해야했습니다 . 언뜻보기에 코드는이 차이점을 언급하지 않은 것 같습니다.
/*
* Not all the page cache can be freed, otherwise the system will
* start swapping. Assume at least half of the page cache, or the
* low watermark worth of cache, needs to stay.
*/
pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
pagecache -= min(pagecache / 2, wmark_low);
available += pagecache;
그러나 Shmem
"사용 된"메모리로 올바르게 취급합니다 . tmpfs에 여러 개의 1GB 파일을 만들었습니다. 1GB 씩 증가 할 때마다 1GB 씩 Shmem
감소 MemAvailable
합니다. 따라서 "파일 LRU 목록"의 크기에는 공유 메모리 또는 다른 교체 가능한 메모리가 포함되지 않습니다. (이러한 페이지 수는 "더티 제한"을 계산하는 코드 에도 사용 됩니다 .)
이 MemAvailable
계산에서는 커널의 "낮은 워터 마크"와 동일한 파일 캐시를 유지하기를 원한다고 가정합니다. 또는 현재 캐시의 절반 (둘 중 작은 쪽) 재생 가능한 슬래브에 대해서도 동일한 가정을합니다. 커널의 "낮은 워터 마크"는 조정할 수 있지만 일반적 으로 시스템 RAM의 약 2 %입니다 . 따라서 대략적인 추정 만 원한다면이 부분을 무시할 수 있습니다 :-).
firefox
페이지 캐시에 약 100MB의 프로그램 코드가 매핑되어 실행될 때 일반적으로 해당 100MB를 RAM에 유지하려고합니다. 그렇지 않으면 기껏해야 지연이 발생할 수 있습니다. 최악의 경우 시스템은 서로 다른 응용 프로그램간에 스 래싱하는 데 모든 시간을 소비합니다 . 따라서이를 MemAvailable
위해 적은 양의 RAM이 허용됩니다. 충분하지 않거나 너무 관대 할 수 있습니다. "이러한 요소의 영향은 시스템마다 다릅니다".
많은 PC 워크로드의 경우 "많은 파일"에 대한 요점은 관련이 없을 수 있습니다. 그럼에도 불구하고 현재 랩톱에 500MB의 재생 가능한 슬래브 메모리가 있습니다 (8GB RAM 중). 이것은 ext4_inode_cache
(300K 개체 이상) 때문입니다. 최근에 디스크 공간을 사용하고있는 것을 찾기 위해 전체 파일 시스템을 스캔해야했기 때문에 발생했습니다 :-). 나는 명령을 사용 df -x / | sort -n
했지만 Gnome Disk Usage Analyzer는 같은 일을 할 것이다.
2. 컨트롤 그룹의 메모리
소위 "리눅스 컨테이너"에서 구축되어 namespaces
, cgroups
및 기타 다양한 기능 :-) 취향에 따라. 그것들은 완전한 리눅스 시스템과 거의 같은 것을 실행하기에 충분한 환경을 제공 할 수 있습니다. 호스팅 서비스는 이와 같은 컨테이너를 구축하고 "가상 서버"로 판매 할 수 있습니다 :-).
호스팅 서버는 또한 기본 Linux에없는 기능을 사용하여 "가상 서버"를 구축 할 수 있습니다. OpenVZ 컨테이너는 메인 라인 cgroup보다 2 년 앞서고 "beancounters"를 사용하여 메모리를 제한 할 수 있습니다. 따라서 기본 Linux 커널에 대한 문서 만 읽거나 질문을하는 경우 메모리 제한이 어떻게 작동하는지 정확하게 이해할 수 없습니다. cat /proc/user_beancounters
현재 사용량과 한계를 보여줍니다. vzubc
좀 더 친숙한 형식으로 표시합니다. beancounters 의 메인 페이지 는 행 이름을 문서화합니다.
제어 그룹에는 내부 프로세스에 대한 메모리 제한을 설정하는 기능이 포함됩니다. 이러한 cgroup 내에서 응용 프로그램을 실행하면 응용 프로그램에서 모든 시스템 메모리를 사용할 수있는 것은 아닙니다. :-). 그렇다면이 경우 사용 가능한 메모리를 어떻게 볼 수 있습니까?
cgroup-v1 또는 cgroup-v2 를 사용하는지 여부에 따라 여러 가지면에서 인터페이스가 다릅니다 .
내 랩탑 설치는 cgroup-v1을 사용합니다. 나는 달릴 수있다 cat /sys/fs/cgroup/memory/memory.stat
. 파일이 포함 다양한 필드를 표시합니다 total_rss
, total_cache
, total_shmem
. tmpfs를 포함한 shmem은 메모리 제한에 포함됩니다. 나는 당신이 total_rss
의 역수로 볼 수 있다고 생각합니다 MemFree
. 그리고 memory.kmem.usage_in_bytes
슬래브를 포함한 커널 메모리를 나타내는 파일도 있습니다 . ( 이것은 명시 적으로 문서화되어 있지는 않지만 memory.kmem.
포함 memory.kmem.tcp.
및 향후 확장을 포함 한다고 가정합니다 ). 재생 가능한 슬래브 메모리를 볼 수있는 별도의 카운터가 없습니다. cgroup-v1에 대한 문서에 따르면 메모리 제한에 도달해도 슬래브 메모리의 재생이 트리거 되지 않습니다 . 또한이 문서에는 "희망스럽게 구식 인"면책 조항이 있으며 현재 소스 코드를 확인해야합니다.
cgroup-v2가 다릅니다. 루트 (최상위) cgroup은 메모리 계정을 지원하지 않는다고 생각합니다. cgroup-v2에는 여전히 memory.stat
파일이 있습니다. 모든 필드가 하위 cgroup에 합산되므로 total_...
필드 를 찾을 필요가 없습니다 . file
같은 일을 한 필드 cache
가 있습니다. 짜증나게 나는 rss
내부 와 같은 전반적인 분야를 보지 못한다 memory.stat
. 개별 필드를 추가해야한다고 생각합니다. 재생 가능 및 재생 불가능한 슬랩 메모리에 대한 별도의 통계가 있습니다. v2 cgroup은 메모리가 부족해지기 시작할 때 슬래브를 재생하도록 설계되었다고 생각합니다.
Linux cgroup은 자동으로 가상화되지 않거나 /proc/meminfo
(또는의 다른 파일 /proc
) 전체 시스템의 값을 표시합니다. 이로 인해 VPS 고객이 혼동 될 수 있습니다. 그러나 네임 스페이스를 사용 하여 특정 컨테이너 소프트웨어에 의해 위조/proc/meminfo
된 파일 로 대체 할 수 있습니다 . 가짜 가치가 얼마나 유용한지는 특정 소프트웨어의 기능에 따라 다릅니다.
systemd
cgroup-v1을 컨테이너에 안전하게 위임 할 수 없다고 생각합니다. systemd-nspawn
cgroup-v1 시스템 의 컨테이너 내부를 살펴 보았습니다 . 내부에 cgroup이 배치되어 있고 메모리가 계산되어 있음을 알 수 있습니다. 반면에 포함 된 내용 systemd
은 자원 계정에 대한 일반적인 서비스 별 cgroup을 설정하지 않습니다. 이 cgroup 내에서 메모리 계정이 활성화되어 있지 않으면 컨테이너가 활성화 할 수 없다고 가정합니다.
cgroup-v2 컨테이너 안에 있다면 실제 cgroup-v2 시스템의 루트와 다르게 보일 것이며 최상위 cgroup에 대한 메모리 계산을 볼 수 있습니다. 또는 cgroup에서 메모리 계정을 사용하도록 설정하지 않은 경우 메모리 계정을 사용하도록 (또는 이와 동등한) 사용systemd
권한을 위임 할 수 있기를 바랍니다 .
MemAvailable
.3.14에 추가되었습니다.