Egloos | Log-in


oom-killer

오늘 저녁을 먹고 파일정리 좀 하려고 노틸러스를 띄웠는데 갑자기 디스크IO가 일어나며 네트웍이 단절되고 마우스도 안움직이고 물론 키보드도 안먹혔습니다. 그냥 껐다켤까 하다 무엇때문에 그럴까 궁금해서 그대로 나뒀습니다.
대략 10분이 경과하고 나니 네트웍이 복구되고 마우스도 움직이더군요. 바로 터미널을 띄워서 dmesg실행. 뭔가 많이 나오더군요. 시간대로 걸러보니 아래 메세지들이 걸리더군요. 무슨일이 일어났던걸까요?

oom-killer: gfp_mask=0x201d2, order=0
 [<c0144b11>] out_of_memory+0x25/0x144
 [<c0145fa7>] __alloc_pages+0x1f5/0x275
 [<c0147117>] __do_page_cache_readahead+0xc8/0x1e8
 [<c01162e5>] __wake_up_common+0x2f/0x53
 [<c0116755>] __wake_up+0x2a/0x3d
 [<c014420e>] filemap_nopage+0x151/0x30b
 [<c014c731>] __handle_mm_fault+0x24e/0x705
 [<c01248a3>] do_gettimeofday+0x31/0xce
 [<c011554e>] do_page_fault+0x18a/0x46c
 [<c01153c4>] do_page_fault+0x0/0x46c
 [<c01037d5>] error_code+0x39/0x40
Mem-info:
DMA per-cpu:
cpu 0 hot: high 0, batch 1 used:0
cpu 0 cold: high 0, batch 1 used:0
DMA32 per-cpu: empty
Normal per-cpu:
cpu 0 hot: high 186, batch 31 used:171
cpu 0 cold: high 62, batch 15 used:16
HighMem per-cpu:
cpu 0 hot: high 186, batch 31 used:149
cpu 0 cold: high 62, batch 15 used:50
Free pages:       21472kB (340kB HighMem)
Active:308610 inactive:1200 dirty:0 writeback:0 unstable:0 free:5368 slab:5431 mapped:76 pagetables:868
DMA free:5120kB min:68kB low:84kB high:100kB active:8156kB inactive:20kB present:16384kB pages_scanned:685 all_unreclaimable? no
lowmem_reserve[]: 0 0 880 1263
DMA32 free:0kB min:0kB low:0kB high:0kB active:0kB inactive:0kB present:0kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 0 880 1263
Normal free:16012kB min:3756kB low:4692kB high:5632kB active:840796kB inactive:2024kB present:901120kB pages_scanned:128967 all_unreclaimable? no
lowmem_reserve[]: 0 0 0 3071
HighMem free:340kB min:380kB low:788kB high:1200kB active:385488kB inactive:2756kB present:393152kB pages_scanned:423692 all_unreclaimable? yes
lowmem_reserve[]: 0 0 0 0
DMA: 0*4kB 0*8kB 0*16kB 38*32kB 5*64kB 0*128kB 0*256kB 1*512kB 1*1024kB 1*2048kB 0*4096kB = 5120kB
DMA32: empty
Normal: 25*4kB 1*8kB 258*16kB 184*32kB 14*64kB 1*128kB 3*256kB 0*512kB 0*1024kB 0*2048kB 1*4096kB = 16012kB
HighMem: 1*4kB 6*8kB 2*16kB 0*32kB 0*64kB 0*128kB 1*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 340kB
Swap cache: add 0, delete 0, find 0/0, race 0+0
Free swap  = 0kB
Total swap = 0kB
Free swap:            0kB
327664 pages of RAM
98288 pages of HIGHMEM
3495 reserved pages
1280 pages shared
0 pages swap cached
0 pages dirty
0 pages writeback
76 pages mapped
5431 pages slab
868 pages pagetables
Out of Memory: Kill process 17809 (nautilus) score 163551 and children.
Out of memory: Killed process 17810 (evince-thumbnai).

처음에는 DMA어쩌고 나와서 디스크가 맛이 갔는줄 알았습니다. 하지만 구글에서 검색해보니 메모리쪽 문제더군요.
리눅스의 메모리 정책은 알다시피 할당요청이 들어오면 일단 허용하고 나중에 실제로 메모리를 할당합니다. 하지만 이 부분이 문제입니다. 아래 3개의 프로그램을 볼까요.

// CODE 1
#include <stdio.h>
#include <stdlib.h>

int main (void) {
    int n = 0;

    while (1) {
        if (malloc(1<<20) == NULL) {
            printf("malloc failure after %d MiB\n", n);
            return 0;
        }
        printf ("got %d MiB\n", ++n);
    }
}


// CODE 2
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main (void) {
    int n = 0;
    char *p;

    while (1) {
        if ((p = malloc(1<<20)) == NULL) {
            printf("malloc failure after %d MiB\n", n);
            return 0;
        }
        memset (p, 0, (1<<20));
        printf ("got %d MiB\n", ++n);
    }
}


// CODE 3
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define N       10000

int main (void) {
    int i, n = 0;
    char *pp[N];

    for (n = 0; n < N; n++) {
        pp[n] = malloc(1<<20);
        if (pp[n] == NULL)
            break;
    }
    printf("malloc failure after %d MiB\n", n);

    for (i = 0; i < n; i++) {
        memset (pp[i], 0, (1<<20));
        printf("%d\n", i+1);
    }

    return 0;
}

1번 프로그램은 메모리를 계속 할당하기만 합니다. 2번은 메모리를 계속 할당하면서 바로 사용합니다. 3번은 메모리를 한꺼번에 할당하고 한꺼번에 사용합니다. 1,2번 같은 경우는 아무문제 없습니다. 할당이 실패하면 바로 프로그램이 종료되니깐요.
문제는 3번입니다. 메모리를 더이상 할당이 불가능할때까지 계속 할당합니다. 이때 커널은 나중에 메모리를 할당하기 때문에 실제 사용 가능한 메모리를 넘어서 할당될 수 도 있습니다. 그 메모리를 건드리지 않으면 별문제 없으나 할당이 종료되고나면 실제 메모리를 쓰기 시작합니다. 이때 실제적인 메모리 할당이 일어나는데 메모리가 모자라므로 Out of memory가 발생합니다. 여기서 oom-killer가 등장합니다. 이 killer는 init를 제외한 현재 실행중인 모든 프로세스를 검사해서 메모리 사용량에 따라 점수를 메깁니다. 이때 superuser프로세서나 하드웨어를 엑세스중인 프로세스는 점수가 1/4로 삭감된다는군요. 하여튼 이렇게 점수를 메겨서 제일 높은 프로세서를 죽여버립니다. 그래서 이름이 킬러인듯..-_-;;
위에 로그 맨아래를 보시면 노틸러스가 163551점으로 당첨되어 죽었습니다.
서버를 운영할때에는 서비스데몬이 oom-killer에게 안죽도록 메모리관리를 잘해야겠더군요. overcommit가능한 용량은 /proc/meminfo의 CommitLimit, Committed_AS를 보시면 됩니다. 그리고 /proc/sys/vm/overcommit_memory와 /proc/sys/vm/overcommit_ratio를 조정하여 overcommit정책을 바꿀 수 있습니다.

by Jihyun | 2006/11/06 21:13 | 트랙백(1) | 핑백(1) | 덧글(0)

트랙백 주소 : http://sylphong.egloos.com/tb/523835
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from 지랄도 떨던놈이 떤다고! at 2007/02/12 16:30

제목 : 리눅스/솔라리스 메모리 관련 이슈 사항입니다.
어플리케이션 서브프로세스를 생성할때 메모리 사용량 최대로 줄이기-한국 썬 자료(레드햇 포함) Understanding Virtual Memory 최근에 운영중인 서버에서 아무리 메모리를 꽂아박아도 서버가 죽어버리는 현상이 발생하는 중이라서 이에 대한 자료를 찾던 중 두 링크를 발견하여 링크 올립니다. 좀 더 살펴본 후 해당 내용(overcommit_memory, overcommit_ratio) 적용을 계획중입니다. 메모......more

Linked at gamoo entertainm.. at 2010/10/28 08:48

... tags: anagram wikipedia) Working Notes on the Linux VM Subsystem (tags: linux kernel memory) sylphong : oom-killer (tags: linux OOMK) Process Virtual Memory Mapping (tags: linux kernel memory) OOM killer ... more

:         :

:

비공개 덧글

◀ 이전 페이지          다음 페이지 ▶