Где происходит эта утечка ParcelFileDescriptor?

Я реализовал BackupAgent, следуя рекомендациям для Резервное копирование данных. Код ведет себя так, как ожидалось, пока StrictMode.VmPolicy не будет настроен на обнаружение утечки закрываемых объектов. После выполнения резервного копирования и сборки мусора CloseGuard сообщает об утечке ParcelFileDescriptor со следующей трассировкой стека:

06-28 21:47:39.683  25072-25081/com.qbix.nub E/StrictMode﹕ A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
    java.lang.Throwable: Explicit termination method 'close' not called
            at dalvik.system.CloseGuard.open(CloseGuard.java:184)
            at android.os.ParcelFileDescriptor.<init>(ParcelFileDescriptor.java:179)
            at android.os.ParcelFileDescriptor$1.createFromParcel(ParcelFileDescriptor.java:905)
            at android.os.ParcelFileDescriptor$1.createFromParcel(ParcelFileDescriptor.java:897)
            at android.app.IBackupAgent$Stub.onTransact(IBackupAgent.java:64)
            at android.os.Binder.execTransact(Binder.java:404)
            at dalvik.system.NativeStart.run(Native Method)
06-28 21:47:39.683  25072-25081/com.qbix.nub W/System.err﹕ StrictMode VmPolicy violation with POLICY_DEATH; shutting down.
06-28 21:47:39.683  25072-25081/com.qbix.nub I/Process﹕ Sending signal. PID: 25072 SIG: 9

Чтобы убедиться, что у меня не было утечки ParcelFileDescriptor в моем BackupAgent, я вставил onBackup() вот так:

@Override
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) throws IOException {
    if (oldState != null) {
        oldState.close();
    }
    newState.close();
    return;
}

Это изменение не устранило утечку.

Вот шаги, которые я использую для воспроизведения проблемы:

  1. Измените данные приложения, чтобы вызвать вызов BackupManager.dataChanged()
  2. Используйте adb shell bmgr run для принудительного выполнения операции резервного копирования
  3. Запустить сборщик мусора с Android Studio

Я недостаточно знаю о связанных службах, чтобы понять, дает ли трассировка стека подсказки о том, происходит ли утечка в системе BackupService или вызвана ошибкой в ​​моем коде, которую я не вижу. Продолжающееся возникновение утечки при работе с заглушкой onBackup() подсказывает мне, что утечка связана с сервисом.

Изучая эту проблему, я обнаружил, что за последние несколько месяцев были опубликованы другие проблемы, которые включали тот же отчет об утечке в их logcats:

Утечка ресурсов в Android

Проблемы с навигационным ящиком в Android

Android - HTTP Get - явное завершение не называется ошибкой. Что мне не хватает?

Устранение исключения java.lang.Throwable в Android

Показанный выше logcat взят с устройства KitKat. Я думаю, что на другом устройстве, на котором запущен Lollipop, возникает та же ошибка. Приложение убито, но logcat не включает дамп CloseGuard. Не знаю, что мне нужно сделать, чтобы это увидеть.


person Bob Snyder    schedule 29.06.2015    source источник
comment
Продолжающееся возникновение утечки при работе с заглушкой onBackup() подсказывает мне, что утечка происходит в сервисе - я согласен. OTOH, я не видел сообщений об этом, и я ожидал бы их, если бы каждая резервная копия в основном содержала ParcelFileDescriptor. Я ненавижу систему резервного копирования по соображениям конфиденциальности и безопасности, поэтому я не использовал ее лично.   -  person CommonsWare    schedule 30.06.2015
comment
Для этого я создал выпуск AOSP 178506.   -  person Bob Snyder    schedule 01.07.2015