美文网首页
TimeoutException crash 整治

TimeoutException crash 整治

作者: jumplover | 来源:发表于2019-10-21 20:14 被阅读0次

    一段时间以来,端上由 TimeoutException 造成的 crash 频发。经过全面排查日志、Crash 共性,发现 TimeoutException 基本上由 FinalizerWatchdogDaemon-> finalizerTimedOut 抛出。

    一、复现问题

    重写 finalize(),在方法内进行耗时操作,并重复创建该类对象。

     @Override
     protected void finalize() throws Throwable {
        Thread.sleep(xxx);
        super.finalize();
     }
    

    果然抛出了 TimeoutException 异常,且在调用链中出现了 FinalizerWatchdogDaemon.finalizerTimedOut。

    注:部分机型不会抛出异常。这部分手机可能在 Rom 层做了优化。

    二、寻找 hook 点

    既然异常由 FinalizerWatchdogDaemon 抛出,接下来就从它入手。

    1. FinalizerWatchdogDaemon 和 FinalizerDaemon 关系较为密切。当对象将被回收时,jvm 会将重写 finalize 的对象存入队列中,由 FinalizerDaemon 统一调用 Object.finalize 方法。

    2. FinalizerWatchdogDaemon 顾名思义是看门狗的一类。它则负责检测 finalize 方法调用是否超时,主要逻辑在 FinalizerWatchdogDaemon.finalizerTimeOut()。

    finalizerTimeOut()

    那么规避 FinalizerWatchdogDaemon 抛出的 TimeoutException 就是让系统无法走到 finalizerTimedOut 的逻辑。finalizerTimedOut 只有一处调用,即 runInternal 。调用 finalizerTimedOut 之前有一个前置条件:返回需要 finalize 的对象不为空。

    runInternal()

    那么我们要做的是只要确保 waitForFinalization 返回对象为空即可。而 waitForFinalization 方法内部有一处校验逻辑:

    if (!sleepFor(MAX_FINALIZE_NANOS)) {
        // Don't report possibly spurious timeout if we are interrupted.
        return null;
    }
    

    即只要耗时没有超过 MAX_FINALIZE_NANOS,返回的对象为空。

    因此解决方案为:加大 MAX_FINALIZE_NANOS 的值:

    try {
        Class<?> clazz = Class.forName("java.lang.Daemons");
        Field field = clazz.getDeclaredField("MAX_FINALIZE_NANOS");
        field.setAccessible(true);
        field.set(null, xxxx); // 改为确定的阀值
        } catch (Exception e) {
          //no-op
        }
    
    

    注:有些 Rom 可能修改了 MAX_FINALIZE_NANOS 值。因此最好在修改前做一个判断,满足一定条件再进行反射修改。另对于 9.0 以上系统可直接返回不做反射处理。

    除了增大阀值,另外还可以直接停止 FinalizerWatchdogDaemon 监听。相对来说风险稍大。可能导致未知问题。

    由于我们的 APP 体量相对还较大。综合比较,选择了增大阀值的方式解决 TimeoutException。另对于这类修改,最好还是通过灰度等方式先行确认改动是否存在问题。

    相关文章

      网友评论

          本文标题:TimeoutException crash 整治

          本文链接:https://www.haomeiwen.com/subject/rzjxvctx.html