Linux 内核有个机制叫OOM killer(Out Of Memory killer),该机制会监控那些占用内存过大,尤其是瞬间占用内存很快的进程,然后防止内存耗尽而自动把该进程杀掉。内核检测到系统内存不足、挑选并杀掉某个进程的过程可以参考内核源代码linux/mm/oom_kill.c,当系统内存不足的时候,out_of_memory()被触发,然后调用select_bad_process()选择一个”bad”进程杀掉。如何判断和选择一个”bad进程呢?linux选择”bad”进程是通过调用oom_badness(),挑选的算法和想法都很简单很朴实:最bad的那个进程就是那个最占用内存的进程。
具体OOM的解释可以看这篇文章:http://www.wowotech.net/memory_management/oom.html
1.那么我们要如何去查看呢?
一个命令:
egrep -i -r 'killed process' /var/log
这个命令需要用户处于root权限才能看,执行之后可以看到:
简单说一下:
total-vm就是进程使用的虚拟内存大小,其中部分内容映射到RAM本身,也就是主存,被分配和使用也就成了RSS。
部分RSS在实际内存块里面分配,成了anon-rss,叫做匿名内存。还有映射到设备和文件的RSS内存卡,叫做file-rss。
比如说:
你用vim指令打开一个巨大的文件,那么file-rss将会很高。
如果你用malloc()动态分配很大部分的内存,并且真的使用了它,那么anon-rss也会很高。
但是!!如果你使用malloc()分配了大量的内存,但是不去用它!那么total-vm将会变得更高,但是因为内存过量使用,不会使用真正的内存,那么rss值会很低。
可以看到上述信息,发现进程被杀掉了。
那么杀掉它的原因是什么呢?
首先确定,当报出OOM的时候,系统的内存已经不足了,于是linux会决定杀掉进程,但是linux采用的策略并非是杀掉最占用内存的进程(Android是这样)。
linux会给每个进程评分:oom_score
根据这个评分去kill,决定这个分数的因素除了内存占用大小之外,还有内存增加的速率,比如说kylin,当执行Task构建Cube的时候,内存的占用会突然爆发式增长!发现这时候的分数老高了!然后就把它kill了。
2.那么如何解决呢?
- 1.增加系统内存
- 2.是优化进程,使其占用内存降低。
- 3.是可以使用oom_score_adj参数,这个参数会被计算影响到oom_score,改了之后就可以避免进程被杀死(不推荐)。
参考:
http://www.wowotech.net/memory_management/oom.html
https://stackoverflow.com/questions/18845857/what-does-anon-rss-and-total-vm-mean