一、out of memory 介绍:
Linux kernel out_of_memory(简称OOM)从字面上看可以就可以看出是因为没有内存可供分配导致,OOM的产
生和内存分配相关,分析此类问题需要对linux kernel的内存管理非常了解才好定位问题。产生OOM的原因大部分是
因为内存的泄漏导致,但也不排除部分小内存的设备(512M或者更低)在使用大量耗内存的应用时,设备的内存回收
机制来不及回收内存也会导致出现无内存分配,MTK 平台产生out of memroy时会出现重启并产生KE的DB文件,将
KE的DB文件使用GAT解析后的log可以获取到产生的原因。从LOG中可以看出OOM触发的流程如下:
<4>[91663.895212]-(3)[19301:InputReader][<c010e618>] (dump_backtrace) from [<c010e950>] (show_stack+0x18/0x1c)
<4>[91663.895219]-(3)[19301:InputReader] r6:60010013 r5:c1454288 r4:00000000 r3:00040975
<4>[91663.895229]-(3)[19301:InputReader][<c010e938>] (show_stack) from [<c04a3968>] (dump_stack+0x94/0xa8)
<4>[91663.895238]-(3)[19301:InputReader][<c04a38d4>] (dump_stack) from [<c02a9e70>] (dump_header+0x90/0xe8)
<4>[91663.895244]-(3)[19301:InputReader] r6:cbf1a300 r5:00000001 r4:d712dcac r3:00040975
<4>[91663.895253]-(3)[19301:InputReader][<c02a9de0>] (dump_header) from [<c0253870>] (oom_kill_process+0x3c0/0x4c4)
<4>[91663.895267]-(3)[19301:InputReader][<c02534b0>] (oom_kill_process) from [<c0253d18>] (out_of_memory+0x104/0x438)
<4>[91663.895274]-(3)[19301:InputReader] r10:00000000 r9:c140c300 r8:c140c308 r7:c140c300 r6:c1404548 r5:d712dcac
<4>[91663.895287]-(3)[19301:InputReader][<c0253c14>] (out_of_memory) from [<c0259718>] (__alloc_pages_nodemask+0xfe4/0x1000)
<4>[91663.895295]-(3)[19301:InputReader] r10:00000000 r9:00000003 r8:c1404a54 r7:000003a3 r6:c153a490 r5:c140468c
<4>[91663.895299]-(3)[19301:InputReader] r4:00000000
OOM处理的机制如下:
- 检查是否配置了/proc/sys/kernel/panic_on_oom,如果是则直接触发panic;
- 检查是否配置了oom_kill_allocating_task,即是否需要kill current进程来回收内存,如果是,且current进程是killable的,则kill current进程;
- 根据既定策略选择需要kill的process,基本策略为:通过进程的内存占用情况计算“点数”,点数最高者被选中;
- 如果没有选出来可kill的进程,那么直接panic;
- kill掉被选中的进程,以释放内存。
__alloc_pages
|-->__alloc_pages_nodemask
|--> __alloc_page