一、前情回顾
GC 的时候,Java 线程、Native 线程都会中断,中断就会卡顿,会影响性能。
上节课提到,执行一次 GC 后,间隔5s 或者 500ms 再次执行一下GC ,这样基本上能触发 GC ,这是什么原理呢?在 Android 5.0 以前,System.gc() 基本上就能触发 GC 行为,它的代码是这样的:
1 | /** |
但是在 5.0 及以后,调用 System.gc 或者 runTime.gc 不一定会触发 GC 了,这是因为在 5.0 及以后的 gc 方法里面会有标记判断:
1 | /** |
可以看到,是否执行 gc 还有赖于 justRanFinalization 变量,这个变量在哪里赋值为true 呢?是在 runFinalization 方法中:
1 | /** |
从上述代码可以看出,我们直接调用 System.gc 并不会调用到 Runtime.getRunTime().gc() ,只是做了个标记将 runGc 设置为 true ,然后在下一次 GC 的时候,就能真正 GC 了。那为什么要间隔5s 或者 500ms 呢?这个跟线程调度、线程的中断状态有关。
所以,上一节课也提到,内存监控自己做 GC 的时候,也可以使用 runFinalization() + runTime.gc 的方式去GC,这样也是可以的。
由于路哥在课程里面对这个讲得不是太清晰,更详细的内容可以参考
二、 Alpha 源码讲解
面试中怎么讲:
Executor :线程池,调用方可以自己实现,也可以使用默认的,参数怎么设置
Task : 是个线程,有任务自己的状态、有自己的子任务
接口: 执行前、执行后、失败
仿照 Alpha 的框架没有实现 DAG 算法,是个弊端
1、主要要实现的功能
线程池、线程等待、线程切换、主进程/子进程
三、总结之前的启动框架
内存、ANR 、启动,这3个点,性能优化就能把握了
四、卡顿
根据前面说的,能够在 Activity 的 onWindowFocusChanged 方法中停止方法的采集,因为这个时候恰好是 window 切换,要么是新的 window 启动了,要么是关闭了某个 window,所以,如果我们要监测到第一个 Activity 的耗时,可以从Application 的 onCreate 中去start,在 MainActivity 中去 stop 这个 trace 去实现:
1 | //Application |
你可以获取到更细粒度更精准的耗时,比如在 ListView 中 getView 方法,在方法调用前start ,在调用完成之后,调用 stop 。
根据上述获取的 trace 文件,拖到 AS 中就能看到方法的耗时,线程相关内容等。
systrace 比上面的方法更加精准。systrace 就是个 shell 脚本嘛,他需要使用 python 执行,比如定位到 SDK 目录下(platform-tools)的 systrace 时,调用 python systrace.py 即可。systrace 可以在 chrome 上打开,使用地址:
chrome://tracing
线上如何做卡顿。卡顿的原理。自己定义阈值,超过某个值就说是卡顿,比如 1000ms ,
CountDownLatch 实现让主线程等待所有的初始化完成才继续执行的。
第一个版本仿照 Alpha ,怎么保证顺序?
第二个版本 DAG (有向无环图)保证顺序