TT 语音线程优化,Android 开发快速学习
}}}normalInfo.append("\n=====================================threadTraceEnd=======================================")Log.i(tag, normalInfo.toString())}}
companion object {const val tag = "====>ThreadCheck"
fun hook() {
if (!BuildConfig.DEBUG) {return}
DexposedBridge.hookAllConstructors(Thread::class.java, ThreadCheck())}}
}
日志打印格式
从上图结合下图可以看出在下面的类创建了 AsyncTask,而且使用完后没有立即销毁,造成了内存的浪费,而且,频繁的创建线程可能会导致 APP 因为线程数量过多造成 OOM
分析
如上图所示,TT 语音在 android8.0 以上的机型上出现的大量这种类似的 OOM,这是因为线程数量过多或者虚拟内存不足造成的,创建线程是需要消耗虚拟内存的,不同机型允许的最大线程数量是不一样的,例如在华为的部分机型上,这个上限被修改的很低(大约 500),需要注意的是,APP 的线程总数=工作中的线程数+sleep 状态的线程数,所以这些手机容易出现线程数溢出的问题,而 TT 语音一进入首页就会大概创建 240 个左右的线程,虽然这里面有很多线程都是很快就工作结束的,然后变成无用线程的,也就是说这些工作结束后的线程并不会计入 APP 的线程总数中,但是,频繁的创建线程依然可能会导致上图中的 OOM,因为尽管他们工作时间很短,但是依然可能是压垮骆驼的最后一根稻草,而且,频繁的创建线程,会造成虚拟内存的消耗,加大 OOM 的可能性,因此,尽量减少线程的创建是线程优化的关键一步,然后,开始统计线程使用情况,情况如下:
线程使用情况
代码中使用 new Thread 或者 new AsyncTask 或者 new HandlerThread 创建的线程,例如上图中创建了 AsyncTask
获取
SharePreferences 对象的时候创建的线程,每次获取 SharePreferences 对象的时候都会重新创建线程,原因是我们获取 SharePreferences 对象的模式是多进程模式,这个情况下每次获取 SharePreferences 对象的时候都会创建新线程 3. 代码中协程创建的线程 4. 第三方 sdk 创建的线程以及获取 SharePreference 对象创建的线程 5. 代码中使用线程池创建的线程 6. Maven 依赖库创建的线程优化方式
获取 SharePreferences 对象的时候考虑数据是否在多个进程中使用,如果不是,将模式改成 MODE_PRIVATE,这样就不会每次获取 SharePreferences 对象的时候都重新创建线程
对于代码中使用 new Thread 或者 new AsyncTask 或者 new HandlerThread 创建的线程,建议改成使用线程池或者协程来复用线程 QQ 交流群
评论