1.问题Log
system_server Crash导致重启
Process: system_server
java.util.concurrent.TimeoutException: android.view.ThreadedRenderer.finalize() timed out after 10 seconds
at android.view.ThreadedRenderer.nDeleteProxy(Native Method)
at android.view.ThreadedRenderer.finalize(ThreadedRenderer.java:448)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:206)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:189)
at java.lang.Thread.run(Thread.java:818)
2.发生时的trace
#java trace
"FinalizerWatchdogDaemon" daemon Sleep
at java.lang.Thread.Sleep(Thread.java:314) //触发crash的watchdog thread
at java.lang.daemon$FinalizerWatchdogDaemon.finalizerTimeout(Daemons.java)
"FinalizerDaemon" daemon Native
-- native trace
at android.view.ThreadedRenderer.nDeleteProxy(Native Method) //和报问题的位置一样
at android.view.ThreadedRenderer.finalize(ThreadedRenderer.java:448)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:206)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:189)
at java.lang.Thread.run(Thread.java:818)
3.触发的具体log
#/libcore/libart/src/main/java/java/lang/Daemons.java
private static void finalizerTimedOut(Object object) {
// The current object has exceeded the finalization deadline; abort!
String message = object.getClass().getName() + ".finalize() timed out after "
+ (MAX_FINALIZE_NANOS / NANOS_PER_SECOND) + " seconds"; //10s
Exception syntheticException = new TimeoutException(message);
// We use the stack from where finalize() was running to show where it was stuck.
syntheticException.setStackTrace(FinalizerDaemon.INSTANCE.getStackTrace());
Thread.UncaughtExceptionHandler h = Thread.getDefaultUncaughtExceptionHandler();
// Send SIGQUIT to get native stack traces.
try {
Os.kill(Os.getpid(), OsConstants.SIGQUIT); //TimeoutException之后杀掉此进程,这里system_server crash
// Sleep a few seconds to let the stack traces print.
Thread.sleep(5000); //sleep 因此trace里面显示的是Sleep状态
} catch (Exception e) {
System.logE("failed to send SIGQUIT", e);
} catch (OutOfMemoryError ignored) {
// May occur while trying to allocate the exception.
}
if (h == null) {
// If we have no handler, log and exit.
System.logE(message, syntheticException);
System.exit(2);
}
// Otherwise call the handler to do crash reporting.
// We don't just throw because we're not the thread that
// timed out; we're the thread that detected it.
h.uncaughtException(Thread.currentThread(), syntheticException);
}
4.原因与解决方法
一般由于系统太忙,无法及时调度,多发于monkey等自动化测试中,monkey中发生可以不用关心
5.修改方案
把timeout时间提高
#/libcore/libart/src/main/java/java/lang/Daemons.java
public final class Daemons {
private static final int NANOS_PER_MILLI = 1000 * 1000;
private static final int NANOS_PER_SECOND = NANOS_PER_MILLI * 1000;
private static final long MAX_FINALIZE_NANOS = 10L * NANOS_PER_SECOND; //改为20