low memory killer究竟是怎么执行起来的呢?不难猜测low memory killer的执行应该是在系统内存不足的时候。那low memory killer会在什麽样的进程中执行呢?我们来构造一个系统memory 不足的场景:我们创建几个“hello world” android app,在每个app中都分配尽可能多的内存(分配内存过多进程会发生OutOfMemoryError并退出),如下面这样,
int[] data; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); data = new int[40 * 1024 *1024]; for (int i = 0; i < data.length; ++ i) { data[i] = i; } }
此处大概会直接分配160MB的内存。让类似这样的几个app在设备上执行起来。随后我们将可以看到内核吐出来的如下的log:
I/KERNEL ( 89): [76545.246439] lowmemorykiller: Killing 'GC' (8807), adj 1000, I/KERNEL ( 89): [76545.246439] Free memory is -12768kB above reserved I/KERNEL ( 89): [76545.247221] lowmemorykiller: Killing 'FinalizerDaemon' (8812), adj 1000, I/KERNEL ( 89): [76545.247221] Free memory is -13388kB above reserved I/KERNEL ( 89): [76545.247844] lowmemorykiller: Killing 'com.android.mms' (7520), adj 1000, I/KERNEL ( 89): [76545.247844] Free memory is -12860kB above reserved I/KERNEL (10682): [76545.251268] lowmemorykiller: Killing 'Chrome_DBThread' (7985), adj 1000, I/KERNEL (10682): [76545.251268] Free memory is -13520kB above reserved I/KERNEL ( 2603): [76545.253024] lowmemorykiller: Killing 'ndroid.settings' (8417), adj 1000, I/KERNEL ( 2603): [76545.253024] Free memory is -13508kB above reserved I/KERNEL (10682): [76545.255380] lowmemorykiller: Killing 'GC' (8421), adj 1000, I/KERNEL (10682): [76545.255380] Free memory is -13532kB above reserved I/KERNEL (10682): [76545.257210] lowmemorykiller: Killing 'FinalizerDaemon' (8426), adj 1000, I/KERNEL (10682): [76545.257210] Free memory is -13124kB above reserved I/KERNEL (10682): [76545.258990] lowmemorykiller: Killing 'FinalizerWatchd' (8427), adj 1000, I/KERNEL (10682): [76545.258990] Free memory is -13520kB above reserved I/KERNEL ( 89): [76545.269048] lowmemorykiller: Killing 'AsyncTask #2' (8550), adj 1000, I/KERNEL ( 89): [76545.269048] Free memory is -11964kB above reserved I/KERNEL ( 89): [76545.269576] lowmemorykiller: Killing 'ndroid.settings' (8556), adj 1000, I/KERNEL ( 89): [76545.269576] Free memory is -11320kB above reserved I/KERNEL ( 89): [76545.277088] lowmemorykiller: Killing '.apps.magazines' (9342), adj 1000, I/KERNEL ( 89): [76545.277088] Free memory is -9760kB above reserved I/KERNEL ( 89): [76545.277722] lowmemorykiller: Killing 'Signal Catcher' (9347), adj 1000, I/KERNEL ( 89): [76545.277722] Free memory is -9264kB above reserved I/KERNEL ( 89): [76545.279231] lowmemorykiller: Killing 'JDWP' (9348), adj 1000, I/KERNEL ( 89): [76545.279231] Free memory is -6512kB above reserved I/KERNEL ( 89): [76545.352095] lowmemorykiller: Killing 'viders.calendar' (7629), adj 1000, I/KERNEL ( 89): [76545.352095] Free memory is -1456kB above reserved I/KERNEL ( 89): [76545.371231] lowmemorykiller: Killing 'droid.deskclock' (8744), adj 1000, I/KERNEL ( 89): [76545.371231] Free memory is -1476kB above reserved I/KERNEL ( 89): [76545.371442] lowmemorykiller: Killing 'Signal Catcher' (8749), adj 1000, I/KERNEL ( 89): [76545.371442] Free memory is -1724kB above reserved I/KERNEL ( 89): [76545.371528] lowmemorykiller: Killing 'Compiler' (8751), adj 1000, I/KERNEL ( 89): [76545.371528] Free memory is -1724kB above reserved I/KERNEL (10682): [76545.400071] lowmemorykiller: Killing 'ndroid.keychain' (9274), adj 1000, I/KERNEL (10682): [76545.400071] Free memory is -13472kB above reserved I/KERNEL (10682): [76545.403081] lowmemorykiller: Killing 'droid.gms.drive' (9220), adj 1000, I/KERNEL (10682): [76545.403081] Free memory is -13596kB above reserved I/KERNEL ( 89): [76545.433711] lowmemorykiller: Killing 'id.defcontainer' (9082), adj 1000, I/KERNEL ( 89): [76545.433711] Free memory is -3472kB above reserved I/KERNEL (10881): [89005.483361] ehci-intel-hsic 0000:00:10.0: irq 36, io mem 0xf9060000 I/KERNEL ( 89): [89020.472924] lowmemorykiller: Killing 'droid.apps.plus' (8492), adj 1000, I/KERNEL ( 89): [89020.472924] Free memory is -1116kB above reserved I/KERNEL ( 89): [89020.474199] lowmemorykiller: Killing 'earchbox:search' (8711), adj 1000, I/KERNEL ( 89): [89020.474199] Free memory is -256kB above reserved
lowmemorykiller运行起来咯。我们可以看到,lowmemorykiller并不是在某个单独的进程或内核线程中的运行的,它实际上会在多个不同的进程中执行。那这都是些什麽进程呢?我们看看这些进程到底是什麽:
root 89 2 0 0 ffffffff 00000000 S kswapd0 root 90 2 0 0 ffffffff 00000000 S ksmd root 2603 1 5880 388 ffffffff ffffe430 S /sbin/adbd root 4658 2603 2480 1628 ffffffff ffffe430 S logcat root 6279 266 852208 23544 ffffffff 6fe583b9 S app_process root 6559 1 2100 1132 ffffffff f76c6913 S /system/bin/debuggerd system 6621 1 59708 36468 ffffffff ffffe430 S /system/bin/surfaceflinger u0_a104 10315 6644 926140 205504 ffffffff ffffe430 S com.example.lowmemorykillertest4 u0_a103 10387 6644 926136 205244 ffffffff ffffe430 S com.example.lowmemorykillertest3 u0_a102 10462 6644 925140 205516 ffffffff ffffe430 S com.example.lowmemorykillertest2 u0_a101 10526 6644 926140 205476 ffffffff ffffe430 S com.example.lowmemorykillertest1 root 10547 2 0 0 ffffffff 00000000 S kworker/3:2 u0_a6 10604 6644 926228 206320 ffffffff ffffe430 S com.hanpfei.concurrencytest u0_a105 10682 6644 941916 219876 ffffffff ffffe430 S com.example.lowmemorykillertest5 root 12149 2 0 0 ffffffff 00000000 S kworker/0:1
执行了lowmemorykiller的进程总共有3个,一个是内核线程kswapd0,另外两个分别是native app adbd和Java app com.example.lowmemorykillertest5。由此,我们推测,lowmemorykiller大概有两种执行方式,一种是在kswapd0中,kswapd0内核线程会被定期唤醒,当它发现系统内存不足的时候,它就会去执行lowmemorykiller杀进程,并回收内存;另外一种是在app中,当一个app请求分配内存,而系统又没有足够的内存可供分配时,则分配内存的请求将会先被阻塞,执行lowmemorykiller杀进程,回收内存之后再尝试着去分配内存。
Done.