当大量内存明显空闲时,进程被 OOM 杀手杀死

当大量内存明显空闲时,进程被 OOM 杀手杀死

我正在开发基于 ARM 的嵌入式平台。 32 位,512MB RAM,无交换区。 Linux 3.10.53(Ubuntu 的某种变体,如果相关的话)。

我正在处理的一些代码不断地被 oom 杀死,尽管我实际测量到的所有内容都表明当它死掉时有足够的内存可用。可能是什么原因造成的?

在运行该进程之前,free -m 报告约320MB免费,也接近 /proc/meminfo 中的 LowFree 数字; ps -e -o vsize 中的所有数字之和约为 212MB,/proc/meminfo 中的平板数据约为 10MB,这间接表明不应使用超过 222MB 的空间,这与以下数据大致一致空闲内存。

然后我运行我的代码,过了一会儿它就被 oom 杀死了。 dmesg 中的注释说该过程有一个总大小 180MB;请注意,这比运行之前据称免费的 300MB 左右要少得多。正是这个进程自己的内存请求触发了 oom-killer。

(这绝对是 oom-killer 杀死了进程;它在 dmesg 中说了这么多,而我的 ulimit 是无限的。)

一个简单的程序

我发现我可以使用一个绝对简单的程序来重现我不理解的关键问题。我将对此进行描述,然后(如果有人关心)返回到最初发送给我的更复杂的程序,我已经在该程序上进行了更广泛的测试。

所以,这里有一些代码。无聊的#includes被省略了。普通的C.

int main(void) {
  int i=0, j;
  char * p;
  while (1) {
    fprintf(stderr, "allocating block %d\n", ++i);
    p = malloc(10000000);
    for (j=0; j<10000000; ++j) p[j] = j; /* touch memory */
  }
  return 0;
}

在运行此程序之前,似乎有大约 320MB 的可用空间。它分配 16 个 10MB 块,然后在尝试分配第 17 个块时被 oom-killed。

好的,现在回到原来的程序。

这个节目最初是关于

如果我使用 strace -e trace=memory 运行进程(以便我看到对 brk 和 m[un]map2 的调用):首先,输出似乎与 180MB 进程大小一致;其次,进程在 oom-killed 之前执行的最后一次分配约为 15MB。

如果我在 gdb 下运行该进程并尽可能停止它直到它终止,那么:

  • /proc/meminfo 的 LowFree 数字仍然约为 230MB
  • /proc/meminfo 中的其他数字似乎都没有表明已使用其他内存(例如,slab 仍然约为 10MB,因此该进程似乎并没有以某种方式使内核分配很多内存)
  • ps 报告该进程的 vsize 约为 165MB(这与 15MB 分配使其达到 180MB 一致,这显然是 oom-killer 杀死它时的情况)
  • gdbinfo proc mappings没有显示任何对我来说可疑的内容,[编辑添加:]除了
    • 它列出的区域之一的名称类似于[stack:14958],数字是我的一个线程的 LWP ID,大小似乎约为 130MB,即使代码中的所有大内存分配都是通过malloc或在堆上进行的new。有一个地区叫 ,heap但它要小得多。
    • 跟踪进程表明所有这些大内存分配实际上都是在幕后映射的;我想这足以解释这一点(因此“堆栈”名称具有误导性);但我无知,因此不确定。 (我已经验证这些 mmap 调用返回的内存块确实位于该区域内。)

(可能相关:当停止在那里时,gdb 开始表现奇怪——例如,continue让它说“警告:无法获取通用寄存器”并且显然无法继续运行程序)这似乎可以想象是由某种资源触发的筋疲力尽。)

[编辑补充:在 gdb 下运行时,进程会提前终止,这并不奇怪,因为 gdb 本身使用了不可忽略的内存量。确切地说,它何时在 gdb 下死亡显然取决于我设置的断点。]

这都是在 vm.overcommit_memory=0 和 vm.overcommit_ratio=50 的情况下实现的。将过量使用比率增加到 90 似乎没有任何改变(但我已经验证 meminfo 中的 CommitLimit 数字适当增加)。

设置 vm.overcommit_memory=2 (我理解应该关闭过度使用)似乎不会改变任何东西,这让我有点困惑(禁用过度使用不应该使分配在进行时失败,而不是成功然后触发oom 杀手?)。

以下是我认为 oom-killer 日志中最相关的信息:

Sep 24 11:02:04 wandboard kernel: MY_PROCESS_NAME invoked oom-killer: gfp_mask=0x2084d0, order=0, oom_score_adj=0
Sep 24 11:02:04 wandboard kernel: CPU: 0 PID: 14294 Comm: MY_PROCESS_NAME Not tainted 3.10.53-1.1.0_ga-wandboard-06034-g13bb184-dirty #1
Sep 24 11:02:04 wandboard kernel: [<80013acc>] (unwind_backtrace+0x0/0xf8) from [<80011544>] (show_stack+0x10/0x14)
Sep 24 11:02:04 wandboard kernel: [<80011544>] (show_stack+0x10/0x14) from [<8067d0cc>] (dump_header.isra.10+0x64/0x188)
Sep 24 11:02:04 wandboard kernel: [<8067d0cc>] (dump_header.isra.10+0x64/0x188) from [<80092170>] (oom_kill_process+0x270/0x3c8)
Sep 24 11:02:04 wandboard kernel: [<80092170>] (oom_kill_process+0x270/0x3c8) from [<80092710>] (out_of_memory+0x27c/0x2d4)
Sep 24 11:02:04 wandboard kernel: [<80092710>] (out_of_memory+0x27c/0x2d4) from [<80096568>] (__alloc_pages_nodemask+0x834/0x85c)
Sep 24 11:02:04 wandboard kernel: [<80096568>] (__alloc_pages_nodemask+0x834/0x85c) from [<800ab4a0>] (__pte_alloc+0x24/0x13c)
Sep 24 11:02:04 wandboard kernel: [<800ab4a0>] (__pte_alloc+0x24/0x13c) from [<800ae474>] (handle_mm_fault+0xdc/0xf0)
Sep 24 11:02:04 wandboard kernel: [<800ae474>] (handle_mm_fault+0xdc/0xf0) from [<800185e4>] (do_page_fault+0x208/0x368)
Sep 24 11:02:04 wandboard kernel: [<800185e4>] (do_page_fault+0x208/0x368) from [<80008370>] (do_DataAbort+0x34/0x9c)
Sep 24 11:02:04 wandboard kernel: [<80008370>] (do_DataAbort+0x34/0x9c) from [<8000deb4>] (__dabt_usr+0x34/0x40)
Sep 24 11:02:04 wandboard kernel: Exception stack(0x8b6a1fb0 to 0x8b6a1ff8)
Sep 24 11:02:04 wandboard kernel: 1fa0:                                     6dd95001 7ed706a8 6cdfffff 000000e6
Sep 24 11:02:04 wandboard kernel: 1fc0: 6dd95001 000006f2 00000603 7ed706c8 0014c0a0 7ed70910 00000003 7ed706f4
Sep 24 11:02:04 wandboard kernel: 1fe0: 6cdffffe 7ed70690 6ce00000 00195a6c 200f0010 ffffffff
Sep 24 11:02:04 wandboard kernel: Mem-info:
Sep 24 11:02:04 wandboard kernel: DMA per-cpu:
Sep 24 11:02:04 wandboard kernel: CPU    0: hi:   42, btch:   7 usd:  33
Sep 24 11:02:04 wandboard kernel: active_anon:44721 inactive_anon:36 isolated_anon:0
Sep 24 11:02:04 wandboard kernel: active_file:7 inactive_file:1 isolated_file:0
Sep 24 11:02:04 wandboard kernel: unevictable:0 dirty:0 writeback:0 unstable:0
Sep 24 11:02:04 wandboard kernel: free:40238 slab_reclaimable:720 slab_unreclaimable:1594
Sep 24 11:02:04 wandboard kernel: mapped:4 shmem:77 pagetables:257 bounce:0
Sep 24 11:02:04 wandboard kernel: free_cma:39999
Sep 24 11:02:04 wandboard kernel: DMA free:160952kB min:1684kB low:2104kB high:2524kB active_anon:178884kB inactive_anon:144kB active_file:28kB inactive_file:4kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:524288kB managed:177468kB mlocked:0kB dirty:0kB writeback:0kB mapped:16kB shmem:308kB slab_reclaimable:2880kB slab_unreclaimable:6376kB kernel_stack:1160kB pagetables:1028kB unstable:0kB bounce:0kB free_cma:159996kB writeback_tmp:0kB pages_scanned:75 all_unreclaimable? yes
Sep 24 11:02:04 wandboard kernel: lowmem_reserve[]: 0 0 0 0
Sep 24 11:02:04 wandboard kernel: DMA: 3486*4kB (UMC) 3056*8kB (UC) 2814*16kB (MC) 2395*32kB (UMC) 14*64kB (MC) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB 0*8192kB 0*16384kB 0*32768kB = 160952kB
Sep 24 11:02:04 wandboard kernel: 90 total pagecache pages
Sep 24 11:02:04 wandboard kernel: 0 pages in swap cache
Sep 24 11:02:04 wandboard kernel: Swap cache stats: add 0, delete 0, find 0/0
Sep 24 11:02:04 wandboard kernel: Free swap  = 0kB
Sep 24 11:02:04 wandboard kernel: Total swap = 0kB
Sep 24 11:02:04 wandboard kernel: 131072 pages of RAM
Sep 24 11:02:04 wandboard kernel: 40500 free pages
Sep 24 11:02:04 wandboard kernel: 4710 reserved pages
Sep 24 11:02:04 wandboard kernel: 1715 slab pages
Sep 24 11:02:04 wandboard kernel: 264131 pages shared
Sep 24 11:02:04 wandboard kernel: 0 pages swap cached
Sep 24 11:02:04 wandboard kernel: [ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name
Sep 24 11:02:04 wandboard kernel: [  254]     0   254      623      154       3        0             0 upstart-udev-br
Sep 24 11:02:04 wandboard kernel: [  269]     0   269     2377      156       6        0         -1000 systemd-udevd
Sep 24 11:02:04 wandboard kernel: [  290]   103   290      889      139       5        0             0 dbus-daemon
Sep 24 11:02:04 wandboard kernel: [  348]     0   348      826       46       4        0             0 bluetoothd
Sep 24 11:02:04 wandboard kernel: [  363]     0   363      841       74       5        0             0 systemd-logind
Sep 24 11:02:04 wandboard kernel: [  436]   109   436      705       86       5        0             0 avahi-daemon
Sep 24 11:02:04 wandboard kernel: [  441]   101   441     7429      206       9        0             0 rsyslogd
Sep 24 11:02:04 wandboard kernel: [  444]   109   444      675       55       5        0             0 avahi-daemon
Sep 24 11:02:04 wandboard kernel: [  539]     0   539     1810      176       7        0             0 cups-browsed
Sep 24 11:02:04 wandboard kernel: [  603]     0   603      486       45       3        0             0 upstart-socket-
Sep 24 11:02:04 wandboard kernel: [  606]     0   606      621      185       5        0             0 upstart-file-br
Sep 24 11:02:04 wandboard kernel: [  704]     0   704      845       29       5        0             0 getty
Sep 24 11:02:04 wandboard kernel: [  705]     0   705      845       29       5        0             0 getty
Sep 24 11:02:04 wandboard kernel: [  709]     0   709      845       29       5        0             0 getty
Sep 24 11:02:04 wandboard kernel: [  710]     0   710      845       29       5        0             0 getty
Sep 24 11:02:04 wandboard kernel: [  713]     0   713      845       29       5        0             0 getty
Sep 24 11:02:04 wandboard kernel: [  734]     0   734     1471      120       6        0         -1000 sshd
Sep 24 11:02:04 wandboard kernel: [  742]     0   742      565       45       5        0             0 cron
Sep 24 11:02:04 wandboard kernel: [  998]     0   998      845       29       5        0             0 getty
Sep 24 11:02:04 wandboard kernel: [  999]     0   999      407       28       5        0             0 getty
Sep 24 11:02:04 wandboard kernel: [ 1024]  1000  1024      676       47       4        0             0 ssh-agent
Sep 24 11:02:04 wandboard kernel: [ 8516]     0  8516     1729      222       7        0             0 cupsd
Sep 24 11:02:04 wandboard kernel: [13071]     0 13071     6958      244      11        0             0 console-kit-dae
Sep 24 11:02:04 wandboard kernel: [13136]     0 13136     8426      155      10        0             0 polkitd
Sep 24 11:02:04 wandboard kernel: [13482]     0 13482     2458      192       8        0             0 sshd
Sep 24 11:02:04 wandboard kernel: [13501]  1000 13501     2458      195       8        0             0 sshd
Sep 24 11:02:04 wandboard kernel: [13504]  1000 13504     1491      553       6        0             0 bash
Sep 24 11:02:04 wandboard kernel: [14291]     0 14291     1432      104       5        0             0 sudo
Sep 24 11:02:04 wandboard kernel: [14294]     0 14294    45100    41145      89        0             0 MY_PROCESS_NAME
Sep 24 11:02:04 wandboard kernel: Out of memory: Kill process 14294 (MY_PROCESS_NAME) score 316 or sacrifice child
Sep 24 11:02:04 wandboard kernel: Killed process 14294 (MY_PROCESS_NAME) total-vm:180400kB, anon-rss:164580kB, file-rss:0kB

如果我理解正确的话(一个很大的如果),order=0 表示我们一次只请求一个页面,这似乎排除了碎片作为罪魁祸首。该报告本身表明有很多空闲页面。这是怎么回事?

相关内容