我无法解释的 OOM 杀手

我无法解释的 OOM 杀手

我不明白为什么当我看到有足够的内存可用时内核会发出这个 oom killer:

我看了之后说有足够的内存

普通的

直接接入

正常自由线

这是一个基于嵌入式 NAND 闪存的设备,具有 256 MB 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

好的,让我们逐一进行检查。

活动内存是被抛到 LRU 堆栈顶部的内存区域(基本上被多次调用)。

非活动内存是指不经常使用的内存,如果需要交换内存,则可以将其作为交换内存。

Free 是真正可用的内存,大约 40Mb。这是怎么回事?

线索就在这些行中:

 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 

这表示内存碎片。这基本上向您显示了连续可用的内存量。这就是您的问题。

在可用的正常内存中,您可用的连续内存不超过 32kb。您的内存碎片化严重。这意味着如果任何应用程序需要分配超过 32k 的空间,则没有内存可用 - 因此 oom killer 会将某些东西踢出,以提供内存来执行此操作。

所以,你可以做什么。

线索这是:

Free swap = 0kB 
Total swap = 0kB 

哦天哪!没有交换!所以,已提交的内存 — — 只是留在那里。如今较新的内核实际上会“整理”内存,使内存区域连续,而较旧的内核则不会这样做。

你有 70Mb 的内存可以已交换!此外,这不会一次性发生,而是逐渐发生,因此不会对您造成影响。但没有交换,所以没有运气。您也没有多少内存用于页面缓存,这对您的系统来说也是不好的,而且很慢。这也可能会给您带来更多可用的连续空间,这对您来说会很好。

我的建议是,给自己留出 768Mb 的交换空间。说实话,不启用它真的会损害你的内核。

交换对于释放未使用的内存(在你的情况下是四分之一)非常重要,也可以避免你在内存中遇到的令人讨厌的碎片问题可以已被换出并释放了更多连续空间。即使它被换回,它可以已被放回内存区域,从而为您提供更大的连续间隙。

相关内容