环景:

Ubuntu 16.04.01

问题描述:

MATLAB跑一段时间发生,就被killed

原因分析:

可能当时是系统资源不够了被oom-killer了进程

在内核检测到系统内存不足后,会触发oom-killer,挑选最占用内存的进程杀掉

grep “Out of memory” /var/log/messages

查看系统日志方法:

egrep -i -r ‘killed process’ /var/log

Linux 分配内存策略

Linux内核根据应用程序的要求来分配内存,由于进程实际上并不会将分配的内存全部使用,所以,为了提高性能,内核采用了一种过度分配内存(over-commit-memory)的策略,来间接利用进程的空闲内存,提高内存的使用效率。一般来说,这没问题。但如果大多数进程都耗光自己的内存,就有麻烦了。因此此时,所有应用程序的内存之和大于物理内存。所以,必须杀掉一部分进程,一般来说,是选内存占用最大的进程杀掉。

解决方案:

oom_badness() 给每个进程打分,根据 points 的高低来决定杀哪个进程,分数越低越不会被杀掉。

这个 points 可以根据 adj 调节,root 权限的进程通常被认为很重要,不应该被轻易杀掉,所以打分的时候可以得到 3% 的优惠(adj -= 30; 分数越低越不容易被杀掉)。我们可以在用户空间通过操作每个进程的 oom_adj 内核参数来使得进程不容易被 OOM killer 选中杀掉。比如,如果不想 test进程被轻易杀掉的话可以找到 matlab运行的进程号后,调整 oom_score_adj 为 -15(注意 points 越小越不容易被杀):

1.#TOP看进程PID

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

423 q 20 0 43.012g 3.688g 708928 S 907.3 11.8 700:23.91 MATLAB

2.#cat /proc/423/oom_score_adj

0

3.#sudo echo -15 > /proc/423/oom_score_adj

也可以完全关闭 OOM killer,但是最好不要这么做

临时生效:

sysctl vm.overcommit_memory=0

sysctl vm.overcommit_memory=1

sysctl vm.overcommit_memory=2

0:表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。

1:表示内核允许分配所有的物理内存,而不管当前的内存状态如何。

2:表示内核允许分配超过所有物理内存和交换空间总和的内存。

永久生效:

vim /etc/sysctl.conf

vm.overcommit_memory=1

sysctl -p