运行脚本被杀

运行脚本被杀

我正在对 30k 张图片运行一个脚本,突然它被终止了。这可能是什么原因造成的?

mona@pascal:~/computer_vision/deep_learning/darknet$ ./darknet coco test cfg/yolo-coco.cfg yolo-coco.weights images
0: Convolutional Layer: 448 x 448 x 3 image, 64 filters -> 224 x 224 x 64 image
1: Maxpool Layer: 224 x 224 x 64 image, 2 size, 2 stride
2: Convolutional Layer: 112 x 112 x 64 image, 192 filters -> 112 x 112 x 192 image
3: Maxpool Layer: 112 x 112 x 192 image, 2 size, 2 stride
4: Convolutional Layer: 56 x 56 x 192 image, 128 filters -> 56 x 56 x 128 image
5: Convolutional Layer: 56 x 56 x 128 image, 256 filters -> 56 x 56 x 256 image
6: Convolutional Layer: 56 x 56 x 256 image, 256 filters -> 56 x 56 x 256 image
7: Convolutional Layer: 56 x 56 x 256 image, 512 filters -> 56 x 56 x 512 image
8: Maxpool Layer: 56 x 56 x 512 image, 2 size, 2 stride
9: Convolutional Layer: 28 x 28 x 512 image, 256 filters -> 28 x 28 x 256 image
10: Convolutional Layer: 28 x 28 x 256 image, 512 filters -> 28 x 28 x 512 image
11: Convolutional Layer: 28 x 28 x 512 image, 256 filters -> 28 x 28 x 256 image
12: Convolutional Layer: 28 x 28 x 256 image, 512 filters -> 28 x 28 x 512 image
13: Convolutional Layer: 28 x 28 x 512 image, 256 filters -> 28 x 28 x 256 image
14: Convolutional Layer: 28 x 28 x 256 image, 512 filters -> 28 x 28 x 512 image
15: Convolutional Layer: 28 x 28 x 512 image, 256 filters -> 28 x 28 x 256 image
16: Convolutional Layer: 28 x 28 x 256 image, 512 filters -> 28 x 28 x 512 image
17: Convolutional Layer: 28 x 28 x 512 image, 512 filters -> 28 x 28 x 512 image
18: Convolutional Layer: 28 x 28 x 512 image, 1024 filters -> 28 x 28 x 1024 image
19: Maxpool Layer: 28 x 28 x 1024 image, 2 size, 2 stride
20: Convolutional Layer: 14 x 14 x 1024 image, 512 filters -> 14 x 14 x 512 image
21: Convolutional Layer: 14 x 14 x 512 image, 1024 filters -> 14 x 14 x 1024 image
22: Convolutional Layer: 14 x 14 x 1024 image, 512 filters -> 14 x 14 x 512 image
23: Convolutional Layer: 14 x 14 x 512 image, 1024 filters -> 14 x 14 x 1024 image
24: Convolutional Layer: 14 x 14 x 1024 image, 1024 filters -> 14 x 14 x 1024 image
25: Convolutional Layer: 14 x 14 x 1024 image, 1024 filters -> 7 x 7 x 1024 image
26: Convolutional Layer: 7 x 7 x 1024 image, 1024 filters -> 7 x 7 x 1024 image
27: Convolutional Layer: 7 x 7 x 1024 image, 1024 filters -> 7 x 7 x 1024 image
28: Local Layer: 7 x 7 x 1024 image, 256 filters -> 7 x 7 x 256 image
29: Connected Layer: 12544 inputs, 4655 outputs
30: Detection Layer
forced: Using default '0'
Loading weights from yolo-coco.weights...Done!

被剛剛

mona@pascal:~/computer_vision/deep_learning/darknet/src$ dmesg | tail -5
[2265064.961124] [28256]  1007 28256    27449       11      55      271             0 sshd
[2265064.961126] [28257]  1007 28257     6906       11      19      888             0 bash
[2265064.961128] [32519]  1007 32519 57295584 16122050   62725 15112867             0 darknet
[2265064.961130] Out of memory: Kill process 32519 (darknet) score 941 or sacrifice child
[2265064.961385] Killed process 32519 (darknet) total-vm:229182336kB, anon-rss:64415788kB, file-rss:72412kB

[2265064.961128] [32519]  1007 32519 57295584 16122050   62725 15112867             0 darknet
[2265064.961130] Out of memory: Kill process 32519 (darknet) score 941 or sacrifice child
[2265064.961385] Killed process 32519 (darknet) total-vm:229182336kB, anon-rss:64415788kB, file-rss:72412kB

进程终止后我有:

$ top | grep -i mem
KiB Mem:  65942576 total,  8932112 used, 57010464 free,    50440 buffers
KiB Swap: 67071996 total,  6666296 used, 60405700 free.  7794708 cached Mem
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                              
KiB Mem:  65942576 total,  8932484 used, 57010092 free,    50440 buffers
KiB Swap: 67071996 total,  6666296 used, 60405700 free.  7794736 cached Mem
KiB Mem:  65942576 total,  8932608 used, 57009968 free,    50448 buffers
KiB Mem:  65942576 total,  8932480 used, 57010096 free,    50448 buffers

我的 vmstat 是:

$ vmstat -s -SM
        64397 M total memory
         8722 M used memory
          305 M active memory
         7566 M inactive memory
        55674 M free memory
           49 M buffer memory
         7612 M swap cache
        65499 M total swap
         6510 M used swap
        58989 M free swap
    930702519 non-nice user cpu ticks
        33069 nice user cpu ticks
    121205290 system cpu ticks
   4327558564 idle cpu ticks
      4518820 IO-wait cpu ticks
          148 IRQ cpu ticks
       260645 softirq cpu ticks
            0 stolen cpu ticks
    315976129 pages paged in
    829418865 pages paged out
     38599842 pages swapped in
     46593418 pages swapped out
   2984775555 interrupts
   3388511507 CPU context switches
   1475266463 boot time
       162071 forks

另一次我运行此脚本时,只使用了 3000 张图像而不是 30k 张,出现了以下错误:

28: Local Layer: 7 x 7 x 1024 image, 256 filters -> 7 x 7 x 256 image
29: Connected Layer: 12544 inputs, 4655 outputs
30: Detection Layer
forced: Using default '0'
Loading weights from yolo-coco.weights...Done!
OpenCV Error: Insufficient memory (Failed to allocate 23970816 bytes) in OutOfMemoryError, file /build/buildd/opencv-2.4.8+dfsg1/modules/core/src/alloc.cpp, line 52
terminate called after throwing an instance of 'cv::Exception'
  what():  /build/buildd/opencv-2.4.8+dfsg1/modules/core/src/alloc.cpp:52: error: (-4) Failed to allocate 23970816 bytes in function OutOfMemoryError

Aborted (core dumped)

如 htop 所示,它使用了我 64G RES 内存中的 61G。

答案1

它是 Linux 内核的 OOM(内存不足)杀手,用于终止该进程。

Linux 内核允许进程过度使用内存,即进程可以映射(例如mmap(2))比实际可用内存更多的内存。这由文件的值定义/proc/sys/vm/overcommit_memory。可能的值:

  • 0:基于启发式的过度提交(默认)
  • 1:总是过度承诺
  • 2:不要过度承诺

过度提交是默认启用的,因为人们认为一个进程不会使用它映射的所有内存,至少不会同时使用。

当某个进程请求分配内存(例如malloc(2))但可用内存不足时,问题就开始了。然后内核将触发 OOM 终止程序,并根据文件中定义的 OOM 分数终止进程,分数范围/proc/PID/oom_score从 0 到 1000,值越高,在出现 OOM 情况时 OOM 终止程序终止进程的可能性就越大。

OOM 分数是通过一个复杂的算法计算出来的,该算法考虑了进程所有者、进程运行了多长时间、有多少子进程、使用了多少内存等等因素。请注意,被所有者root的进程的实际 OOM 分数始终会被扣除 30 分(当 >=30 时)。

您可以通过在文件中自己提供调整分数来影响 OOM 分数/proc/PID/oom_score_adj,允许值范围从 -1000 到 +1000,负数表示保留进程,正数表示影响终止。因此,您可以检查oom_score相关进程的,并进行必要的调整,以便 OOM 终止程序在开始终止时不会将其列入优先级列表中。但请注意,当您试图保留的进程实际上占用了内存时(如您的情况),不建议这样做。

替代解决方案显然包括安装更多内存,最好检查程序中是否可以做任何事情,例如改变它的算法,或者通过例如施加资源限制cgroups,我担心这可能会导致同样的情况。

答案2

虽然在系统内存耗尽时过度使用内存杀死进程是一个相对明智的决定,但是禁用过度使用只会使占用大量内存的程序异常终止或崩溃,因为它无法分配更多内存来执行其任务。

解决这个问题的唯一方法是

  • 不要用该程序对特定数据集执行特定任务,

  • 调整程序及其操作模式以使用更少的内存——许多数据处理算法都有这样的选项,尽管这个程序的细节是另一个问题——,

  • 终止同时运行的其他不重要的、占用内存的进程,

  • 添加更多身体的主存储器(RAM)到系统,

  • 添加更多虚拟的主内存(交换空间)到系统 - 一旦物理内存耗尽,这显然会减慢系统速度,但至少您的进程最终会完成其工作,这也是另一个问题。

相关内容