ThreadedRenderer.finalize() timed out

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

猜你喜欢

转载自blog.csdn.net/wd229047557/article/details/81672790