이 메모리 문제를 정상적으로 해결하는 방법은 무엇입니까?


10

스왑 파티션이있는 표준 Linux (Debian testing) 랩톱이 있습니다.

나는 그것에 대해 많은 실험을한다. 그들 중 일부는 실제로 메모리가 배고프고 Linux가 기본적으로 동작하는 방식은 나에게 문제입니다 ... 어리석은 예를 들어 봅시다.

  1. 노트북 앞에 앉아
  2. 터미널을 엽니 다
  3. 을 입력 python한 다음a = [0]*100000000

이제 큰 목록을 처리하기에 충분한 RAM이 없을 가능성이 높습니다. 리눅스는 RAM을 채운 다음 스왑을하고 몇 분 후에 OOM 킬러는 (거의) 임의의 서비스를 차단하고, 좋은 시간에 Ctrl + C를 python누르면 터미널이 여전히 초점이 맞으면 컴퓨터가 다시 반응하게됩니다.

원치 않는 스와핑을 피하고 RAM보다 많은 메모리를 할당 할 수있는 권한을 프로세스에 거부하기 위해 메모리 제한을 적용하고 싶습니다. 메모리 요구가 특정 제한 이하이거나 루트에 의해 요청 된 경우 루트를 제외한 모든 사용자의 메모리 사용량이 많은 프로세스를 종료하십시오.

ulimit -Sv [mem] 뒤에서 들린다!

호호! "을 cgroups통해 사용하십시오 cgexec!" 누군가 첫 줄에 말합니다!

예, 그렇습니다. 이들은 실제로 매우 훌륭한 솔루션입니다. 그러나:

  • 그들은 시스템 전체에 적용되지 않습니다
  • 한계는 프로세스마다 설정됩니다
  • 실제 RAM 여유 공간 (AFAIK)을 무시하고 제한이 정적 인 상태입니다.
  • 여기거기 , 그들이 말하는 이들은 정말 열심히 제한을 적용 할 수있는 좋은 해결책이 아니다.

커널은 " 루트가 아닌 사용자 foo에 속해 있으며 , 많은 메모리를 사용하고 있으며 메모리가 부족합니다. 죄송합니다. 친구는 지금 죽으세요!"라고 말합니다.

또는 : "도대체 뭐하는 당신은 필요 X MB를 만이 Y MB 가능 예, SWAP이 비어있는,하지만 당신은 당신이 당신의 더러운 일을하는 SWAP을 사용하지 않을 아니, 난.? "아니요. 당신을위한 기억이 없습니다! 당신이 고집하면 죽을 것입니다!"


2
이 기사 에는 이미 OOM 킬러가 올바른 프로세스를 선택하는 데 도움 되는 알고리즘 있습니다. 변경 /proc/sys/vm/overcommit_memory은 메모리 부족의 커널 동작에 영향을줍니다.
jofel

1
예, 그러나 overcommit_memory특수 파일은 RAM + SWAP를 사용 가능한 메모리로 사용합니다. 난 여전히 스왑거야 :)

1
또한 이것이 unix.stackexchange.com/questions/34334/… 와 중복되지 않는 방법을 설명해야합니다. 이는 WRT cgroup 및 개별 사용자와 모순됩니다. 추신. 교환하지 않으려면 swap을 비활성화하십시오 .
goldilocks

1
스왑을 원합니다! 최대 절전 모드를 원하고 사용하지 않는 바이트를 저장 하고 싶습니다 ! 그러나 사용 된 바이트를 저장 하고 싶지 않습니다 . 링크에 관해서는 ulimits프로세스 당 제한이기 때문에 거의 모든 곳에서 볼 수 있듯이 나쁜 생각입니다. 나는 당신이 알고있는 포크입니다 cgroups. 세 사람이 공유 할 "계산"서버를 소유합니다. 이러한 사용자 당 한도를 적용하면 최악의 시나리오에 의해 제한을 받습니까?

1
cgroup은 사용자의 모든 프로세스를 별도의 그룹에 넣는 모든 프로세스에 적용되며 원하는 작업을 수행해야합니다.
peterph

답변:


4

누군가 당신의 의견을 제안했습니다 cgroups. 글쎄, 당신에게 제공 할 수있는 방향을 찾으십시오.

  • 선택한 작업 그룹에 적용됨 (따라서 시스템 전체가 아니라 프로세스별로)
  • 그룹에 대한 제한이 설정됩니다
  • 한계는 정적이다
  • 그들은 메모리 및 / 또는 메모리 + 스왑에 대한 하드 제한을 시행 할 수 있습니다

그와 같은 것이 목표에 더 가까이 갈 수 있습니다 .

group limited {
  memory {
    memory.limit_in_bytes = 50M;
    memory.memsw.limit_in_bytes = 50M;
  }
}

이 cgroup의 작업은 최대 50M의 메모리 만 사용하고 50M의 메모리 + 스왑을 사용할 수 있으므로 메모리가 가득 차면 스왑되지 않지만 메모리가 가득 차지 않고 일부 데이터가 매핑 될 수 있습니다 스왑, 이것이 허용 될 수 있습니다.

다음은 cgroup의 메모리 설명서 에서 발췌 한 것입니다 .

memsw limit을 사용하면 스왑 부족으로 인해 발생할 수있는 시스템 OOM을 피할 수 있습니다.


여전히 내가 기대했던 것과 정확히 일치하지는 않습니다. 그러나 내가 기대하는 것과 현실의 차이는 종종 상당히 큽니다.이 경우 overcommit_memory커널 변수 와 같은 것을 놓치지 않도록하고 싶었습니다 . 다들 감사 해요.

0

같은 문제가 자주 발생합니다. 필자의 일반적인 작업 과정에는 MATLAB에서 많은 계산이 필요합니다. 때로는 사용 가능한 메모리 양을 초과하는 새 변수를 실수로 할당하려고 시도합니다. 시스템이 중단되고 일반적으로 시스템을 하드 재부팅하여 작업을 다시 시작해야합니다. :피

필자의 경우와 마찬가지로 들리지만 MATLAB이 사용하는 메모리 양을 정적 양으로 제한하는 데 크게 신경 쓰지 않았습니다. 냉동기가없는 기계에 관심이 없었으며 MATLAB 프로세스를 기꺼이 희생했습니다. 시스템 응답 성을 유지하기 위해.

이 게시물 에 대한 응답에서 영감을 얻어 다음 스크립트를 작성했습니다 (watch_memory.sh라고 함).

#!/bin/bash

MONITOR=$(free | grep 'buffers/cache:')
MEM_USED=$(echo $MONITOR | awk '{ print $3 }')
MEM_FREE=$(echo $MONITOR | awk '{ print $4 }')

MEM_PERC=$(( 100*MEM_USED / (MEM_FREE+MEM_USED) ))

while :; do
    if [ "$MEM_PERC" -gt "95" ]
    then
        kill $1
        echo "$1 killed for using too much memory."
        exit
    fi
    sleep 1

    MONITOR=$(free | grep 'buffers/cache:')
    MEM_USED=$(echo $MONITOR | awk '{ print $3 }')
    MEM_FREE=$(echo $MONITOR | awk '{ print $4 }')
    MEM_PERC=$(( 100*MEM_USED / (MEM_FREE+MEM_USED) ))
done

이 스크립트는 사용 가능한 메모리의 백분율 양을 1 초마다 확인합니다. 시스템이 소진되면 "scapegoat"pid (스크립트에 대한 인수로 전달됨)가 종료됩니다.

대본의 우선 순위 (niceness)를 조정하지 않고 희생양을 죽이는 데 약 10-20 초가 걸렸지 만 여전히 작동했습니다. 우선 순위가 마이너스 인 스크립트를 실행하면 위반 후 즉시 강제 종료됩니다 (이 예에서 11916은 메모리가 부족한 경우 종료하려는 pid입니다).

sudo nice -n -5 bash watch_memory.sh 11916
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.