版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011033906/article/details/89959735
这里我会具体分析一个 system crash(原文:安卓开发中遇到的奇奇怪怪的问题(三)),以后面试用来吹比也是可以的
推荐阅读
- 提升Android下内存的使用意识和排查能力
- 再谈Finalizer对象–大型App中内存与性能的隐性杀手
- https://blog.csdn.net/qq_17766199/article/details/84789495#t1
Crash log :
java.util.concurrent.TimeoutException:
android.os.BinderProxy.finalize() timed out after 10 seconds
at android.os.BinderProxy.destroy(Native Method)
at android.os.BinderProxy.finalize(Binder.java:459)
1. 寻找共性
主要集中在 oppo
5.0~6.0 及个别 华为 5.0机型
2. 查看错误堆栈信息
FinalizerWatchdogDaemon
java.util.concurrent.TimeoutException
android.os.BinderProxy.finalize() timed out after 120 seconds
android.os.BinderProxy.destroy(Native Method)
android.os.BinderProxy.finalize(Binder.java:547)
java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:214)
java.lang.Daemons$FinalizerDaemon.run(Daemons.java:193)
java.lang.Thread.run(Thread.java:818)
3. 分析
在 GC
时,为了减少应用程序的停顿,会启动四个 GC
相关的守护线程.FinalizerWatchdogDaemon
就是其中之一,它是用来监控 FinalizerDaemon
线程的执行。
FinalizerDaemon:析构守护线程。对于重写了成员函数finalize的对象,它们被GC决定回收时,并没有马上被回收,而是被放入到一个队列中,等待FinalizerDaemon守护线程去调用它们的成员函数finalize,然后再被回收。
一旦检测到执行成员函数 finalize
时超出一定的时间,那么就会退出 VM
。我们可以理解为 GC
超时了。这个时间默认为 10s
,我通过翻看 oppo
、华为的 Framework
源码发现这个时间在部分机型被改为了 120s
和 30s
。
虽然时间加长了,但还是一样的超时了,具体在oppo手机上为何这么慢,暂时无法得知,但是可以肯定的是 Finalizer
对象过多导致的。知道了原因,所以要模拟这个问题也很简单了。也就是引用一个重写 finalize
方法的实例,同时这个 finalize
方法有耗时操作,这时我们手动 GC
就行了。Demo。