部分OPPO機型 AssetManager.finalize() timed out的修復

在線上的APP常常收到以下的崩潰報告java

.finalize() timed outandroid

image.png

在排除了內存泄漏的狀況後,仔細覈查後發現多發在OPPO系列的機型中,包括R9 A33 A59等等。猜想是OPPO的定製ROM在底層作了什麼修改。爲了減小這樣的報錯,只有對OPPO進行特殊處理。 查找了一些資料後發現這類錯誤是因爲回收對象時間過長,由FinalizerWatchdogDaemon負責計時,超時後拋出異常關閉VM的。 那麼有兩種解決辦法:bash

1關掉這個負責計時的,2延長計時時間ide

try {
    Class clazz = Class.forName("java.lang.Daemons$FinalizerWatchdogDaemon");
    Method method = clazz.getSuperclass().getDeclaredMethod("stop");
    method.setAccessible(true);
    Field field = clazz.getDeclaredField("INSTANCE");
    field.setAccessible(true);
    method.invoke(field.get(null));
} catch (Throwable e) {
    e.printStackTrace();
}
複製代碼

或者字體

try {
    Class<?> c = Class.forName("java.lang.Daemons");
    Field maxField = c.getDeclaredField("MAX_FINALIZE_NANOS");
    maxField.setAccessible(true);
    maxField.set(null, Long.MAX_VALUE);
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} catch (NoSuchFieldException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
}
複製代碼

參考文檔ui

[1]stackoverflow How to handle :java.util.concurrent.TimeoutException: android.os.BinderProxy.finalize() timed out after 10 seconds errors?spa

[2]courtier博客 關於TimeoutException這件小事code

新增說明

形成這個錯誤的緣由應該是過於頻繁的建立對象,最好檢查項目中的代碼確保沒有這種狀況。 一個被普遍使用的屏蔽系統字體大小設置的方法cdn

@Override
 public Resources getResources() {
        Resources res = super.getResources();
        Configuration config=new Configuration();
        config.setToDefaults();
        res.updateConfiguration(config,res.getDisplayMetrics());
        return res;
}
複製代碼

這個方法將在每次getResources調用時new一個Configuration對象,這將致使部分機型來不及回收形成finalize() timed out錯誤。 正確的寫法應該是寫在生命週期方法中 如Activity的onCreate中對象

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    updateConfiguration();
    ......
}
private void updateConfiguration() {
    Resources res = getResources();
    Configuration config = new Configuration();
    config.setToDefaults();
    res.updateConfiguration(config, res.getDisplayMetrics());
}
複製代碼
相關文章
相關標籤/搜索