zoukankan      html  css  js  c++  java
  • 【Android】LMK 工作机制

    Android分析之LowMemoryKiller

     

    Android Kernel 会定时执行一次检查,杀死一些进程,释放掉内存。

        那么,如何来判断,那些进程是需要杀死的呢?答案就是我们的标题:Low memory killer机制。

     

    Low memory killer 则是定时进行检查。

    Low memory killer 主要是通过进程的oom_adj 来判定进程的重要程度。这个值越小,程序越重要,被杀的可能性越低。

    oom_adj的大小和进程的类型以及进程被调度的次序有关。

    Low memory killer 的具体实现可参看:kernel/drivers/misc/lowmemorykiller.c 

    1.oom_adj的值是如何赋予的

    进程的类型,可以在ActivityManagerService中清楚的看到: 

        static final int EMPTY_APP_ADJ;

        static final int HIDDEN_APP_MAX_ADJ;

        static final int HIDDEN_APP_MIN_ADJ;

        static final int HOME_APP_ADJ;

        static final int BACKUP_APP_ADJ;

        static final int SECONDARY_SERVER_ADJ;

        static final int HEAVY_WEIGHT_APP_ADJ;

        static final int PERCEPTIBLE_APP_ADJ;

        static final int VISIBLE_APP_ADJ;

        static final int FOREGROUND_APP_ADJ;

        static final int CORE_SERVER_ADJ = -12;

        static final int SYSTEM_ADJ = -16; 

       ActivityManagerService定义各种进程的oom_adj,CORE_SERVER_ADJ代表一些核心的服务的omm_adj,数值为-12,这类进程永远也不会被杀死。

    其他未赋值的都在static块中进行了初始化,是通过system/rootdir/init.rc进行配置的:

    init.rc中:

    # Define the oom_adj values for the classes of processes that can be

    # killed by the kernel.  These are used in ActivityManagerService.

       setprop ro.FOREGROUND_APP_ADJ 0

       setprop ro.VISIBLE_APP_ADJ 1

       setprop ro.SECONDARY_SERVER_ADJ 2

       setprop ro.HIDDEN_APP_MIN_ADJ 7

       setprop ro.CONTENT_PROVIDER_ADJ 14

       setprop ro.EMPTY_APP_ADJ 15

     

    # Define the memory thresholds at which the above process classes will

    # be killed.  These numbers are in pages (4k).

       setprop ro.FOREGROUND_APP_MEM 1536

       setprop ro.VISIBLE_APP_MEM 2048

       setprop ro.SECONDARY_SERVER_MEM 4096

       setprop ro.HIDDEN_APP_MEM 5120

       setprop ro.CONTENT_PROVIDER_MEM 5632

       setprop ro.EMPTY_APP_MEM 6144

    配置文件有如下两个:

    /sys/module/lowmemorykiller/parameters/adj

    /sys/module/lowmemorykiller /parameters/minfree

    owmeme_adj中各项数值代表阈值的警戒级数,

    lowmem_minfree代表对应级数的剩余内存。

    adj文件存放着oom_adj 内存警戒值( 以4K为单位)
     
    0 1536 
    1 2048 
    2 4096 
    7 5120 
    14 5632 
    15 6144

    也就是说,当系统的剩余内存为小于6MB时候,警戒级数为0,当系统内存剩余小于8M而大于
    6M的时候,警戒级数为1,当内存小于64M大于16MB的时候,警戒级数为12.

     

     

    对于某些小内存设备,我们可以调整对应的门限值,例如:
    一般调整后三个值。
    echo “1536,2048,4096,15360,17920,20480″>/sys/module/lowmemorykiller/parameters/minfree

    原文作者:AndyTsui

    原文链接:http://blog.csdn.net/AndyTsui/archive/2011/02/27/6210653.aspx

    2.LMK的工作机制

     
    LMK开始工作时,
    首先根据阈值表确定当前的警戒级数,则高于警戒级数的进程是待杀的范围。
    然后遍历所有进程的oom_adj值,找到大于min_adj的进程,若找到多个,则把占用进程最大的进程存放在selected中。
     
    最关键的一步就是,发送SIGKILL信息,杀掉该进程。
     

    3.tips

     
    (1)在init.rc中配置:
    # Write value must be consistent with the above properties.
       write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15
     
       write /proc/sys/vm/overcommit_memory 1
       write /sys/module/lowmemorykiller/parameters/minfree 1536,2048,4096,5120,5632,6144
     
       class_start default
    
    

    (2)进程oom_adj同样可以进行设置,通过write /proc/<PID>/oom_adj  ,在init.rc中,init进程的pid1omm_adj被配置为-16,永远不会被杀死。

       # Set init its forked children's oom_adj.
       write /proc/1/oom_adj -16
    (3)dumpsys activity可以dump进程的信息,查看adj值
       procrank可以查看进程占用内存大小

     

  • 相关阅读:
    HTML基础
    Java基础05-计算机单位
    Java基础04-运算符
    Java基础03-数据类型
    Java基础02-变量
    Java基础01-HelloWorld
    MarkDown基本使用
    短视频学习
    c# as 总结
    在C#中使用Nullable类型和 tuple类
  • 原文地址:https://www.cnblogs.com/rayray/p/3413688.html
Copyright © 2011-2022 走看看