Linux에 메모리가 부족할 때 작업을 트리거하는 방법은 무엇입니까?

Linux에 메모리가 부족할 때 작업을 트리거하는 방법은 무엇입니까?

그래서 저는 이것이 매우 간단한 수정이 될 것이라고 생각했습니다. 커널이 사용자 영역에 메모리가 부족하다는 것을 알 때 일부 작업을 트리거하는 서비스/커널 모듈입니다(예: 프로세스 목록을 파일에 덤프, 특정 네트워크 끝점에 핑 실행 등). )) 자체 개인 메모리가 있는 프로세스에서(따라서 fork()에 실패하거나 다른 일반적인 OOM 문제가 발생하지 않습니다).

찾았어요OOM 킬러, 이것이 유용하다는 것을 알고 있지만 실제로 필요한 작업을 수행하지는 않습니다.

이상적으로는 메모리가 부족한 경우 그 이유를 알고 싶습니다. 부팅 시 실행되고 고정된 양의 메모리를 사용하며 커널에서 메모리 부족 알림을 받을 때만 작업을 수행하는 자체 프로그램을 작성할 수 있다고 가정합니다. 하지만 그렇게 하면 자체적으로 문제가 발생할 수 있습니다...

비슷한 것을 알릴 수 있는 시스템 호출이 있습니까? 커널에 "메모리가 128MB만 남으면 깨워주세요"라고 말하는 방법은 무엇입니까?

온라인과 여기에서 검색했지만 해당 설명에 맞는 항목을 찾지 못했습니다. 대부분의 사람들이 시간 지연을 위해 폴링을 사용하는 것처럼 보이지만 분명한 문제는 어떤 프로세스가 문제를 일으키는지 알 가능성이 낮다는 것입니다.

답변1

예, Linux 커널은 이에 대한 메커니즘을 제공합니다.메모리 부족 알림. 이 내용은 다음과 같이 기록됩니다.https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt, 부분기억력 압박.

즉, /sys/fs/cgroup/memory/memory.pressure_level알림을 받고 싶은 eventfd 파일 설명자를 등록합니다. 이러한 알림은 , 또는 일 lowmedium있습니다 critical. 일반적인 사용 사례는 임박한 OOM 종료를 방지하기 위해 알림을 받을 때 프로세스의 내부 캐시 중 일부 또는 전부를 해제하는 것입니다.

답변2

당신이 요구하는 것은 기본적으로 메모리 부족 시 커널 기반 콜백입니다. 그렇죠? 그렇다면 나는 커널이 그렇게 한다고 굳게 믿습니다.아니요그러한 메커니즘을 제공하고,그리고 정당한 이유는 다음과 같습니다.메모리가 부족하므로 메모리를 확보할 수 있는 유일한 작업인 OOM 킬러를 즉시 실행해야 합니다. 다른 프로그램으로 인해 컴퓨터가 중지될 수 있습니다.

어쨌든 사용자 공간에서는 간단한 모니터링 솔루션을 실행할 수 있습니다. 나는 과거에도 동일한 낮은 메모리 디버깅/조작 요구 사항을 갖고 있었고 다음을 수행하는 간단한 bash를 작성했습니다.

  • 모니터하다소프트 워터마크:메모리 사용량이 이 임계값을 초과하는 경우 일부 통계(프로세스, 여유/사용된 메모리 등)를 수집하고 경고 이메일을 보냅니다.

  • 감시 장치하드 워터마크:메모리 사용량이 이 임계값을 초과하면 일부 통계를 수집하고 더 많은 메모리를 소비하는(또는 덜 중요한) 프로세스를 종료하고 경고 이메일을 보냅니다.

이러한 스크립트는 매우 가벼우며 매우 짧은 간격(예: 15초)으로 시스템을 폴링할 수 있습니다.

답변3

현재 가장 좋은 대답은 cgroups-v1입니다. cgroups-v2의 경우 memory.events파일에 대한 파일 수정 이벤트를 수신할 수 있습니다 (문서문서 내용).

다음과 같은 몇 가지 셸 명령을 사용하여 이 파일의 동작을 실제로 테스트할 수 있습니다.

# Spawn a new slice with memory limits to avoid OOMing the entire system
systemd-run --pty --user -p MemoryMax=1050M -p MemoryHigh=1000M bash

# Watch memory.events for changes and read when changed
inotifywait -e modify -m /sys/fs/cgroup$(cut -d: -f3 /proc/self/cgroup)/memory.events \
  | while read l; do echo $l; cat ${l// *}; done &
# Consume memory
tail /dev/zero

불행하게도 이는 cgroup에 실제로 메모리 제한이 설정된 경우에만 작동하는 것 같습니다. 대안으로 다음이 가능합니다.듣기 기억력 압박, 그러나 이는 cgroup 기반이 아니며(적어도 루트가 아닌 사용자의 경우) 반응이 좋지 않습니다.

관련 정보