zoukankan      html  css  js  c++  java
  • [KERNEL OOM] debug linux out of memory的一些技巧

    一、OOM处理的基本流程简单描述如下:

    1、检查是否配置了/proc/sys/kernel/panic_on_oom,如果是则直接触发panic。

    2、检查是否配置了oom_kill_allocating_task,即是否需要kill current进程来回收内存,如果是,且current进程是killable的,则kill current进程。

    3、根据既定策略选择需要kill的process,基本策略为:通过进程的内存占用情况计算“点数”,点数最高者被选中。

    4、如果没有选出来可kill的进程,那么直接panic(通常不会走到这个流程,但也有例外,比如,当被选中的进程处于D状态,或者正在被kill)

    5、kill掉被选中的进程,以释放内存。

    二、log如下:

    [12418.531836] Kernel panic - not syncing: Out of memory and no killable processes...

    [12418.531836]

    [12418.540906] CPU: 0 PID: 14016 Comm: MtkCam3::readou Tainted: P           O    4.9.118+ #1

    [12418.549088] Hardware name: M7642 (DT)

    [12418.552752] Call trace:

    [12418.555212] [<ffffff8008092d3c>] dump_backtrace+0x0/0x298

    [12418.560616] [<ffffff8008093100>] show_stack+0x20/0x28

    [12418.565678] [<ffffff8008554c5c>] dump_stack+0x8c/0xb0

    [12418.570739] [<ffffff80081dcb2c>] panic+0x14c/0x294

    [12418.575536] [<ffffff80081e42c0>] out_of_memory+0x28c/0x2dc

    [12418.581028] [<ffffff80081ec164>] __alloc_pages_nodemask+0xc94/0xcb8

    [12418.587300] [<ffffff80081e1e58>] filemap_fault+0x3a0/0x574

    [12418.592793] [<ffffff8008355c7c>] ext4_filemap_fault+0x3c/0x58

    [12418.598546] [<ffffff8008220410>] __do_fault+0x94/0x128

    [12418.603692] [<ffffff8008232d54>] handle_mm_fault+0x1238/0x2a6c

    [12418.609533] [<ffffff80080afb28>] do_page_fault+0x2a8/0x3b0

    [12418.615023] [<ffffff80080afd90>] do_translation_fault+0x68/0x74

    [12418.620947] [<ffffff8008082330>] do_mem_abort+0x6c/0xe8

    [17222.814487] DMA: 234*4kB (ME) 22*8kB (E) 19*16kB (UE) 0*32kB 0*64kB 1*128kB (C) 1*256kB (C) 0*512kB 2*1024kB (C) 2*2048kB (C) 18*4096kB (C) = 81672kB

    [17222.828137] Movable: 10423*4kB (M) 7129*8kB (M) 4184*16kB (M) 2143*32kB (M) 1088*64kB (M) 407*128kB (M) 135*256kB (M) 38*512kB (M) 19*1024kB (M) 8*2048kB (M) 79*4096kB (M) = 769412kB

    [17222.874947] SLUB: Unable to allocate memory on node -1, gfp=0x2080021(GFP_ATOMIC|GFP_DMA)

    [17222.883128]   cache: dma-kmalloc-128, object size: 128, buffer size: 128, default order: 0, min order: 0

    [17222.892613]   node 0: slabs: 489, objs: 15648, free: 0

    [17222.897767] Unable to handle kernel NULL pointer dereference at virtual address 00000000

    [17222.905859] pgd = ffffffc04b2fc000

    [17222.909260] [00000000] *pgd=0000000000000000, *pud=0000000000000000

    [17222.915558] Internal error: Oops: 96000045 [#1] PREEMPT SMP

    [17222.921134] Modules linked in: wlan(PO) wlan_prealloc(O) bt_usb_qcom(O) tntfs(PO) uhid devnode dtv_driver(O) mdrv_tuner_si_2151 mstar_fbdev_mi(O) mali_kbase(O) mik(O) misck(PO) HEAAC_ENC(PO) mwgifker(PO) xcker(PO) hdcp2x(O) hdcp1x(O) iniparser(O) utpa2k(O) mdrv_ldm(O) kdrv_hdr10plus_ref(O) kdrv_tch_vision(O) kdrv_dolby_vision(O) kdrv_alg(O) kdrv_xc(O) kdrv_platform(O)

    [17222.954070] CPU: 0 PID: 14016 Comm: MtkCam3::readou Tainted: P        W  O    4.9.118+ #1

    [17222.962249] Hardware name: M7642 (DT)

    [17222.965912] task: ffffffc051f05000 task.stack: ffffffc01f50c000

    [17222.971839] PC is at __memcpy+0x7c/0x180

    [17222.975776] LR is at usbRxIntrComplete+0x140/0x210 [bt_usb_qcom]

    Out of memory and no killable processes表示已经没有可以kill的进程了,这时的OOM大概率是系统没有内存可用。

    LOG

    [17222.814487] DMA: 234*4kB (ME) 22*8kB (E) 19*16kB (UE) 0*32kB 0*64kB 1*128kB (C) 1*256kB (C) 0*512kB 2*1024kB (C) 2*2048kB (C) 18*4096kB (C) = 81672kB

    代表的意思是,当前系统中DMA可用内存状态,其中4K块还有234个可用,8K块还有22个可用,16K块还有19个可用,32K、64K、512K块均使用完,128K、256K块有1个可用,2048K块还有2个可用,4096K块还有18个可用。

    Dumpsys meminfo可以输出每个进程的内存使用状态,也可以查看user/kernel内存使用状态。如下是截取的user/kernel的使用状态:

    Total PSS by process:

         70,191K: system (pid 1881)

         52,207K: dtv_svc (pid 1489)

         45,190K: com.google.android.tts (pid 4356)

         38,810K: browser (pid 1921)

         33,456K: com.google.android.gms (pid 3456)

         31,450K: com.android.systemui (pid 2163)

         28,998K: com.google.android.gms.persistent (pid 3003)

         27,725K: zygote (pid 1351)

         24,927K: com.google.android.tungsten.setupwraith (pid 3196 / activities)

         23,614K: com.google.android.youtube.tv (pid 4287)

         17,052K: com.android.tv.settings (pid 2359)

         16,848K: com.google.android.videos (pid 4213)

         16,313K: com.android.vending (pid 3299)

           ……

    Total RAM: 3,082,100K (status normal)

     Free RAM: 2,134,585K (  172,185K cached pss +   247,512K cached kernel + 1,714,888K free)

     Used RAM:   833,008K (  519,596K used pss +   313,412K kernel)

     Lost RAM:   114,503K

         ZRAM:         4K physical used for         0K in swap (  102,396K total swap)

       Tuning: 192 (large 512), oom   120,000K, restore limit    40,000K (high-end-gfx)

    从以上打印可以看出,一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS

    VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)是单个进程全部可访问的地址空间

    RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)是单个进程实际占用的内存大小,对于单个共享库, 尽管无论多少个进程使用,实际该共享库只会被装入内存一次。

    PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)

    USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)USS 是一个非常非常有用的数字, 因为它揭示了运行一个特定进程的真实的内存增量大小。如果进程被终止, USS 就是实际被返还给系统的内存大小。

    USS 是针对某个进程开始有可疑内存泄露的情况,进行检测的最佳数字。怀疑某个程序有内存泄露可以查看这个值是否一直有增加

    其中可以看到user使用约519M,kernel使用约313M,如果是user使用过大,可以在上面的进程使用状态中查到是哪个进程占用过大内存,如果是kernel使用过大,需要开kmemleak来检查。

    Kmemleak使用

    1. 在uboot的bootarg中加入"kmemleak=on"

    2. 在.config中使能如下配置

          CONFIG_HAVE_DEBUG_KMEMLEAK=y

    CONFIG_DEBUG_KMEMLEAK=y

    CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=400

    3. mount -t debugfs nodev /sys/kernel/debug/

          确认是否有如下文件:

          /sys/kernel/debug # ls

          ...

    kmemleak

    /sys/kernel/debug #

    4. 等待系统的memleak检测线程调度(最长10min),或者你可以执行如下的命令强制系统去检测内存泄露,也可以手动触发,执行命令:

          echo scan > /sys/kernel/debug/kmemleak

    5. 随后系统将检测到内存泄露,并通知你去查看

          kmemleak: 2 new suspected memory leaks (see /sys/kernel/debug/kmemleak)

    6. 查看可能的内存泄露点

          Cat /sys/kernel/debug/kmemleak

    注:修改default scan时间可以修改:

          #define SECS_SCAN_WAIT        600   /*subsequent auto scanning delay*/

    内存泄漏的问题,需要在复制过程中,每隔一段时间, dumpsys meminfo和cat /proc/meminfo.

    关于内存操作的一些命令:

    Free 查看内存使用状态

    Ulimit –a 查看内存预设值

    cat /proc/slabinfo 查看slab信息

    Cat /proc/meminfo 查看系统内存使用状态

    内存  shell dumpsys meminfo

    CPU   shell dumpsys cpuinfo

    帧率  shell dumpsys gfxinfo

    显示  shell dumpsys display

    电源  shell dumpsys power

    电池状态     shell dumpsys batterystats

    电池  shell dumpsys battery

    闹钟  shell dumpsys alarm

    位置  shell dumpsys location

  • 相关阅读:
    v-bind绑定属性
    vue 第二次学习笔记 v-once v-html
    P4428-[BJOI2018]二进制【树状数组,set】
    P5180-[模板]支配树
    《架构之美》阅读笔记一
    Python基础04----条件控制
    Tensorflow2.0笔记33——Keras 来搭建神经网络的“八股”套路
    每周总结
    架构漫谈阅读笔记01
    Tensorflow2.0笔记32——卷积神经网络
  • 原文地址:https://www.cnblogs.com/smilingsusu/p/12795596.html
Copyright © 2011-2022 走看看