사용 가능한 메모리가 충분할 때 커널이 왜 이 oom Killer를 발행하는지 이해할 수 없습니다.
또한 왜 그렇게 많은 커널 캐시 페이지가 할당됩니까? 읽고 나니 기억력은 충분하다고 하더군요.
정상
DMA
일반 유휴 회선
256MB RAM을 갖춘 임베디드 낸드 플래시 기반 장치입니다.
커널: 2.6.31
myshellscript invoked oom-killer: gfp_mask=0xd0, order=2, oomkilladj=0
Backtrace:
[<c0106494>] (dump_backtrace+0x0/0x110) from [<c03641a0>] (dump_stack+0x18/0x1c)
r6:000000d0 r5:c9040c60 r4:00000002 r3:c0448690
[<c0364188>] (dump_stack+0x0/0x1c) from [<c015a314>] (oom_kill_process.clone.11+0x60/0x1b4)
[<c015a2b4>] (oom_kill_process.clone.11+0x0/0x1b4) from [<c015a738>] (__out_of_memory+0x154/0x178)
r8:c21e86e0 r7:001fb000 r6:00000002 r5:000000d0 r4:c9b6e000
[<c015a5e4>] (__out_of_memory+0x0/0x178) from [<c015a980>] (out_of_memory+0x68/0xa0)
[<c015a918>] (out_of_memory+0x0/0xa0) from [<c015d230>] (__alloc_pages_nodemask+0x42c/0x520)
r5:00000002 r4:000000d0
[<c015ce04>] (__alloc_pages_nodemask+0x0/0x520) from [<c015d388>] (__get_free_pages+0x18/0x44)
[<c015d370>] (__get_free_pages+0x0/0x44) from [<c0109418>] (get_pgd_slow+0x1c/0xe0)
[<c01093fc>] (get_pgd_slow+0x0/0xe0) from [<c0129ab0>] (mm_init.clone.43+0xb0/0xf0)
r7:c90858c0 r6:00000000 r5:c90858c0 r4:ce1a6680
[<c0129a00>] (mm_init.clone.43+0x0/0xf0) from [<c0129c40>] (mm_alloc+0x34/0x44)
r6:0009230c r5:c90858c0 r4:ce1a6680 r3:00000000
[<c0129c0c>] (mm_alloc+0x0/0x44) from [<c0180f70>] (bprm_mm_init+0x14/0x148)
r4:c5154000 r3:cd472564
[<c0180f5c>] (bprm_mm_init+0x0/0x148) from [<c01812d0>] (do_execve+0xa8/0x254)
[<c0181228>] (do_execve+0x0/0x254) from [<c0106000>] (sys_execve+0x3c/0x5c)
[<c0105fc4>] (sys_execve+0x0/0x5c) from [<c0102e80>] (ret_fast_syscall+0x0/0x2c)
r7:0000000b r6:0009230c r5:0009237c r4:000922fc
Mem-info:
DMA per-cpu:
CPU 0: hi: 18, btch: 3 usd: 0
Normal per-cpu:
CPU 0: hi: 42, btch: 7 usd: 0
Active_anon:28162 active_file:16 inactive_anon:18037
inactive_file:13 unevictable:0 dirty:0 writeback:0 unstable:0
free:9998 slab:2447 mapped:164 pagetables:701 bounce:0
DMA free:17128kB min:1560kB low:1948kB high:2340kB active_anon:51068kB inactive_anon:10320kB active_file:24kB inactive_file:0kB unevictable:0kB present:97536kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 158 158
Normal free:22864kB min:2600kB low:3248kB high:3900kB active_anon:61580kB inactive_anon:61828kB active_file:40kB inactive_file:52kB unevictable:0kB present:162560kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 0 0
DMA: 2358*4kB 912*8kB 25*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB 0*8192kB 0*16384kB = 17128kB
Normal: 4266*4kB 657*8kB 32*16kB 1*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB 0*8192kB 0*16384kB = 22864kB
26591 total pagecache pages
0 pages in swap cache
Swap cache stats: add 0, delete 0, find 0/0
Free swap = 0kB
Total swap = 0kB
65536 pages of RAM
10471 free pages
3967 reserved pages
2447 slab pages
892 shared page count
389 shared pages
620 mapped shared page count
177 mapped shared pages
0 pages swap cached
2481 dma reserved pages
19892 total user pages
20512 RSS sum by tasks
20512 RSS sum by page stats
164 user cache pages
26427 kernel cache pages
답변1
편집: 이 답변은 올바르지 않습니다. oom-killer를 호출하는 이유는 여전히 가능하지만 이 경우에는 이유가 아닙니다.
메모리 조각화로 인해 발생하는 것으로 보입니다.
제공한 출력에 따르면 가장 높은 순서의 연속 메모리 블록은 normal
해당 영역의 32kb 블록입니다. 이는 32kb보다 큰 메모리 블록을 할당하려고 시도하면 실패한다는 의미입니다.
일반적으로 이는 반드시 oom-killer가 호출된다는 의미는 아니지만(그렇지 않으면 응용 프로그램이 많은 메모리를 요청하여 OOM을 트리거할 수 있음) 이는 메모리를 할당하려고 하는 커널이므로 좀 더 심각합니다. 이 경우 새 프로세스를 시작하여 할당이 트리거되고 커널이 해당 프로세스에 메모리를 할당하려고 시도하는 것처럼 보입니다.
커널은 자동으로 메모리를 압축(조각 모음)하고 더 큰 연속 메모리 블록을 확보하려고 시도하지만 일부 페이지는 이동할 수 없습니다. 그리고 시스템이 오래 실행될수록 이러한 "이동할 수 없는" 페이지는 더 분산됩니다.
따라서 기본적으로 할 수 있는 일은 없습니다. 실제로 유일한 옵션은 이동할 수 없는 페이지를 해제하기 위해 프로세스를 종료하는 것입니다.
위 출력에서 메모리 조각화를 나타내는 내용은 다음과 같습니다.
DMA: 2358*4kB 912*8kB 25*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB 0*8192kB 0*16384kB = 17128kB
Normal: 4266*4kB 657*8kB 32*16kB 1*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB 0*8192kB 0*16384kB = 22864kB
이와 같은 항목은 32*16kb
32개의 16kb 연속 여유 메모리 블록이 있음을 의미합니다.
답변2
알려지지 않은 임베디드 플랫폼에서 알려지지 않은 애플리케이션을 다루고 있습니다. 분명히, 우리가 이 두 가지 사항에 대해 더 많은 정보를 가지고 있다면 abc의 질문에 답할 가능성이 더 높아질 것입니다. 스크립트가 확보하려고 하는 메모리 양을 정확히 아는 것도 유용합니다.
나는 Patrick이 옳다고 생각합니다. 프로세스를 실행할 수 있는 연속 DMA가 충분하지 않습니다. 이는 다음과 같은 이유 때문일 수 있습니다.
- 임베디드 시스템에는 맞춤형 페이징 구현이 있을 수 있습니다.
- 임베디드 시스템에는 MMU가 없을 수 있습니다.
- 이 스크립트는 DMA에 대한 정확한 액세스를 위해 IO 드라이버를 호출할 수 있습니다.
- 이 스크립트에는 연속 메모리가 필요한 타사 프로그램이 포함되어 있을 수 있습니다.
등...
DMA 메모리 조각화를 줄이면 OOM Killer가 점프하지 않을 것이라고 믿습니다. 빠르게 테스트하는 가장 쉬운 방법은 내장 장치를 재부팅하고 OOM-killer가 여전히 호출되는지 확인하는 것입니다.
지금은 장치를 재설정하지 않고도 메모리 조각 모음을 수행할 수 있는 가볍고 임베디드 친화적인 방법을 찾기 위해 인터넷을 계속 검색하겠습니다.
다음 링크에 관심이 있을 수 있습니다. http://bl0rg.krunch.be/oom-frag.html