LeakCanary 只能在线下,不能用于线上。LeakCanary 有什么缺点?线上怎么做?
只能对 Acitvirty 和 Fragment 去做
强引用:宁愿 OOM 也不会回收的
软引用:内存足够的时候,即时发生GC,也不会被回收,但是内存不足的时候,就回收了
一、OOM 与内存优化
启动优化,APM 框架
日志系统,使用 mmap 系统崩了也不会丢
使用 xlog
Linux 内核动态内存分配,所以 MemAvailable 不一定准确
RSS 实际使用的物理内存——包含了 共享库的内存(so动态链接库),所以容易误导
python 做自动化测试,python 不断读取那些数据
Android 会对所有进程分类,每一个类别都有其 oom_adj 的值取值范围, oom_adj 的值越大,说明越不重要。因此,内存不足 kill 进程时,从 oom_adj 高的进程开始杀
如果想要一个服务长期运行,应该将其运行在单独的进程里,即 UI进程与 Service 进程分离,这样就能获得较小的 oom_adj 值,就容易存活。而占有大量内存的 UI 进程会分类为 Cached 进程,能够在需要的时候更快地被回收。
LeakCanary 的源码
里面注册了 ContentProvider ,为啥?
线上监测
端上解析:就是在设备上做引擎解析,自己解析内存泄漏
后台解析: 内存镜像,fork 出当前进程,然后将子进程信息发给后台
监测 Activity 生命周期可以使用 RegisterActivityLifecycleCallback 的方式,然后使用 WeakHashMap 来监测回收,因为 WeakHashMap 它的 Key 是弱引用,它里面有个 ReferenceQueue 。
在 ActivityLifecycleCallback 的 onActivityDestroy 回调中,以 Activity 的方式作为 key ,value 可以使用 activity.getClass().getSimpleName(),在 WeakHashMap 中就可以监听 key 的回收,就能监听 Activity 的回收了。类似于如下代码:
1 | WeakHashMap<Activity, String> datas = 。。。 |
然后,在 onActivityStopped 回调中,因为 activity 此时不可见了,可以使用 GC 来找泄漏的 Activity :
1 | public void onActivityStopped(){ |
当然,这里面还需要很多判断,比如判断 Activity 是否在后台。有个同学提出了,如果面试官说这里每次 Activity 的 onStop 都去做这些操作,是否合理?那也确实不合理,假如,只是做了 Activity a 跳转到 Activity b,触发了 a 的 onStop ,这里就有点浪费。所以呢,这里还需要判断 ,其实也是判断 Activity 是否在后台(可能不一定对,听课是这样理解说判断是否在后台)。
这里获取 pss 也能生成曲线图,这个曲线图有什么用呢?就是监测在运行某个功能时,内存占用的问题,就能定向排查问题
爱奇艺的 xhook ,用于 nativeHook
路哥性能优化课程的产出:
启动优化框架
简单的 APM 框架