在项目中遇到服务被偶然杀死的问题,通过kernel log看到:
lowmem_shrink: 5 callbacks suppressed lowmemorykiller: [ pid ] uid tgid total_vm rss swap cpu oom_score_adj name lowmemorykiller: [ 121] 0 121 131 38 18 0 -941 ueventd lowmemorykiller: [ 128] 1023 128 884 65 30 0 -941 sdcard lowmemorykiller: [ 129] 0 129 358 31 4 1 -941 healthd lowmemorykiller: [ 130] 1000 130 254 44 15 0 -941 servicemanager lowmemorykiller: [ 131] 0 131 1171 73 69 0 -941 vold lowmemorykiller: [ 132] 1000 132 786 53 21 0 -941 download lowmemorykiller: [ 133] 1000 133 767 42 36 1 -941 modem_control lowmemorykiller: [ 134] 1000 134 1540 48 40 0 -941 modemd lowmemorykiller: [ 135] 1000 135 1334 56 51 0 -941 wcnd lowmemorykiller: [ 136] 1000 136 90 3 3 0 -941 batterysrv lowmemorykiller: [ 137] 1000 137 749 40 30 0 -941 modemDriver_vpa lowmemorykiller: [ 138] 0 138 2452 89 84 1 -941 netd lowmemorykiller: [ 143] 0 143 284 43 34 1 -941 debuggerd lowmemorykiller: [ 144] 0 144 1509 150 47 0 -941 slog lowmemorykiller: [ 146] 1000 146 11892 920 124 0 -941 surfaceflinger lowmemorykiller: [ 147] 0 147 51702 2089 1565 0 -941 zygote lowmemorykiller: [ 148] 1019 148 2949 159 172 0 -941 drmserver lowmemorykiller: [ 149] 1013 149 12314 345 537 0 -941 mediaserver lowmemorykiller: [ 150] 1012 150 251 47 32 1 -941 installd lowmemorykiller: [ 151] 1017 151 842 62 80 1 -941 keystore lowmemorykiller: [ 153] 2000 153 328 62 63 0 -941 slogmodem lowmemorykiller: [ 154] 0 154 267 35 30 0 -941 srtd lowmemorykiller: [ 155] 1000 155 1456 96 63 0 -941 thermald lowmemorykiller: [ 162] 0 162 267 25 31 1 -941 srtd lowmemorykiller: [ 164] 1000 164 7750 116 107 0 -941 phoneserver lowmemorykiller: [ 165] 0 165 3723 201 299 1 -941 engpc lowmemorykiller: [ 166] 1001 166 2728 168 49 1 -941 rild_sp lowmemorykiller: [ 170] 1001 170 2459 141 46 1 -941 rild_sp lowmemorykiller: [ 171] 0 171 1308 88 765 1 -941 cp_diskserver lowmemorykiller: [ 172] 2000 172 234 31 29 0 -941 sh lowmemorykiller: [ 175] 0 175 2927 91 260 0 -941 engpc lowmemorykiller: [ 179] 1023 179 884 53 46 1 -941 sdcard lowmemorykiller: [ 182] 0 182 1380 58 62 0 -941 collect_apr lowmemorykiller: [ 183] 1000 183 799 49 40 1 -941 refnotify lowmemorykiller: [ 561] 1000 561 83930 5461 2529 0 -941 system_server lowmemorykiller: [ 629] 1001 629 83097 5956 1728 0 -705 m.android.phone lowmemorykiller: [ 639] 10035 639 61751 4469 1329 0 -705 ndroid.systemui lowmemorykiller: [ 716] 10029 716 53242 1687 1869 0 58 android.smspush lowmemorykiller: [ 759] 10014 759 56097 3128 1370 0 294 d.process.acore lowmemorykiller: [ 777] 10040 777 60884 3855 1364 0 0 ndroid.incallui lowmemorykiller: [ 792] 1000 792 53277 1435 2135 1 -705 eadst.validator lowmemorykiller: [ 799] 10000 799 54030 1440 2137 0 -705 oid.modemassert lowmemorykiller: [ 1036] 2000 1036 892 42 7 1 -941 adbd lowmemorykiller: [ 5576] 10039 5576 55422 3100 1298 0 470 yscale.atclient lowmemorykiller: [ 5982] 10013 5982 54468 3466 1259 1 529 com.svox.pico lowmemorykiller: [ 6022] 1000 6022 7750 116 107 0 -941 phoneserver lowmemorykiller: Killing 'com.svox.pico' (5982), adj 9, lowmemorykiller: Killing 'yscale.atclient' (5576), adj 8, //这是我的应用包名,显示的不全 lowmemorykiller: Killing 'oadcastreceiver' (6139), adj 9, lowmemorykiller: Killing 'com.android.mms' (6096), adj 9,
从Log中看到我应用的adj等级为8,所以需要降低这个值,越小越不容易被杀死。
方法一
在代码里面调用 startForeground/stopForeground 添加为前台程序/去掉前台程序
//在onCreate()/onStartCommand()方法 /** * 设置前台进程 */ private void startForegournd() { Notification notification = new Notification(); Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); //把该service创建为前台service startForeground(8888, notification); } //onDestory()方法 stopForeground(true);
方法二
设置为系统应用
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:persistent="true" android:sharedUserId="android.uid.system" package="com.flyscale.atclient">
设置好后,查看adj值,方法如下:
//oom_adj代表当前进程的优先级,这个优先级是kernel中的优先级 adb shell shell@sp9820w_modem:/ $ ps u0_a39 798 146 243272 17252 ffffffff 00000000 S com.flyscale.atclient //pid为798 shell@sp9820w_modem:/ $ cat proc/798/oom_adj 1 //adj值变为1了
其它命令
查看低内存管理的adj值及对应的内存限值
shell@sp9820w_modem:/ $ cat /sys/module/lowmemorykiller/parameters/adj 0,1,2,3,9,15 //说明的系统分为0,1,2,3,9,15这7个等级,为什么是7个?因为这几个值只是一个分界线
越小越难被杀死,前台程序是0,init进程是-16。在init.rc里面有这样一句话 write /proc/1/oom_adj -16
上面的等级对应的低内存回收极限可以通过下面的命令查看
shell@sp9820w_modem:/ $ cat /sys/module/lowmemorykiller/parameters/minfree 2560,3840,4608,6144,7680,9216
例如:当内存低于9216时,会杀掉adj>=15的进程
- 对每个进程来说:
/proc/pid/oom_adj:代表当前进程的优先级,这个优先级是kernel中的优先级,这个优先级与上层的优先级之间有一个换算。
/proc/pid/oom_score_adj:上层优先级,跟ProcessList中的优先级对应