Android 内存管理
2019-10-08 本文已影响0人
___刘辉良
碎碎念
Android
系统是基于Linux
内核开发的操作系统。但是也有差异的。而内存管理就是其中的一处。
- 传统的
Linux
系统的使用的是Swap
交换空间。大致就是当系统内存空间不够的时候,就会释放一些长时间没有使用的程序的内存空间。这些被释放的空间临时存储在swap
空间中。而这部分空出来的内存,就提供给当前需要使用的程序使用。等程序再次要运行的时候被保存在swap
空间中的数据会再次被恢复。 - 而在
Android
又是另一种策略,Android
会持续保存你所运行的进程(为了下次的相应更加的迅速)这样就会存在有一个问题,那就是内存会随着进程的数量随之增大。当系统内存不足的时候,就会触发OOM killer
来对进程管理。OOM killer
就是根据一系列策略和规则来决定杀死进程。
那么,它的规则和策略是什么呢?
Android 进程的分类
在了解它的规则之前,我们先来看下Android
对进程的分类。
- 前台进程( foreground process):顾名思义就是当前正在运行的进程。其中可以是
活动
执行onResume
方法,或者广播
正在执行onReceive
中这类进程都可以被定义成前台进程。当然前台进程也有可能被销毁。当系统的内存空间不足以支撑当前存在的前台进程,这些进程还是会被杀死。 - 可见进程(visible process):正在执行用户可知的工作。这样的话终止它就会影响到用户的体验。其中可以是
活动
的onPause
被调用了,但是对用户还是可见的(比方说当前的活动
是个透明的对话框,可以看到之前的活动
)这样可以被定义为可见进程。可见进程被杀死的优先级会高于前台进程
- 服务进程(service process):是使用
startService()
方法启动的服务。虽然这些进程对用户来说不是直接可见的,但它们通常在做用户关心的事情(比如上传或下载后台网络数据),所以系统将始终保持这些进程的运行,除非没有足够的内存来保留所有前台进程
和可见进程
服务的优先级也会随着运行时间的正常而变大。(运行比较久的服务,会变成缓存进程) - 缓存进程(cached process) :缓存的进程是当前不需要的进程,所以当其他地方需要内存时,系统可以随意终止它。当系统内存不足的时候会优先确保所有的缓存线程都被杀死,还不足以提供内存的时候,才会考虑杀死服务进程。
当我们了解了进程的这些分类,就会知道,当应用程序属于缓存进程
的时候最容易被OOM killer
杀死,如果不想让OOM killer
杀死的话,应该尽量的让我们的应用程序属于前台进程
。
当然这只是官方文档上的说明,我们能不能真正量化它的优先级呢?
OOM_ADJ 介绍
OOM_ADJ
(Out of Memory Adjustment)是android
系统在内存不足情况下进行内存调整的重要参数。我们可以根据这个值,来查看进程被杀死的有限级。OOM_ADJ
的值越大,被OOM killer
杀死的优先级越高。
我们可以通过adb shell ps
来查看进程的PID
,然后通过PID
获取到OOM_ADJ
的值
可以看到当前的微信的oom_adj
的值为8,那么我将微信切换到前台看看会不会发生变化.
可以看到此刻变小了,就意味着更不容易被
OOM killer
杀死了,同时也再次证明了,缓存进程
被OOM killer
杀死的优先级要高。
进程保活的一些看法
进程保活的本质,就是让APP
尽量不被系统杀死。就算杀死了,也要重新force
出来。看过很多文章介绍这个,其中包含有
- 通过监听各种广播,然后来唤醒
APP
- 全家桶系列,比如说你装了
某宝
就会有惊喜。 -
1px
让进程属于可见进程
- 疯狂启动服务
- 白名单
上述的很多方式,随着google
的不断升级,已经失效了。
- Android M Doze Mode
- Android N Limit Implicit Broadcast
- Android O Background Service Limitations
真的很讨厌,那种杀不死的小强。