처리 방법 : java.util.concurrent.TimeoutException : android.os.BinderProxy.finalize ()가 10 초 오류 후에 시간 초과 되었습니까?


167

에 및 의 숫자가 표시 TimeoutExceptions됩니다 . 이 중 90 % 이상이 Android 4.3에서 발생합니다. 우리는 현장의 사용자들로부터 크 리터 시즘으로부터 이것을보고하고 있습니다.GcWatcher.finalize, BinderProxy.finalizePlainSocketImpl.finalize

여기에 이미지 설명을 입력하십시오

오류는 " com.android.internal.BinderInternal$GcWatcher.finalize() timed out after 10 seconds" 의 변형입니다.

java.util.concurrent.TimeoutException: android.os.BinderProxy.finalize() timed out after 10 seconds
at android.os.BinderProxy.destroy(Native Method)
at android.os.BinderProxy.finalize(Binder.java:459)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:187)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:170)
at java.lang.Thread.run(Thread.java:841)

지금까지 우리는 집에서 문제를 재현하거나 그 원인을 알아 낸 운이 없었습니다.

어떤 아이디어가 이것을 일으킬 수 있습니까? 이것을 디버깅하고 앱의 어느 부분이 이것을 일으키는 지 알아내는 방법에 대한 아이디어가 있습니까? 이 문제를 밝히는 모든 것이 도움이됩니다.

더 많은 스택 추적 :

1   android.os.BinderProxy.destroy  
2   android.os.BinderProxy.finalize Binder.java, line 482
3   java.lang.Daemons$FinalizerDaemon.doFinalize    Daemons.java, line 187
4   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
5   java.lang.Thread.run    Thread.java, line 841  

2

1   java.lang.Object.wait   
2   java.lang.Object.wait   Object.java, line 401
3   java.lang.ref.ReferenceQueue.remove ReferenceQueue.java, line 102
4   java.lang.ref.ReferenceQueue.remove ReferenceQueue.java, line 73
5   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
6   java.lang.Thread.run

1   java.util.HashMap.newKeyIterator    HashMap.java, line 907
2   java.util.HashMap$KeySet.iterator   HashMap.java, line 913
3   java.util.HashSet.iterator  HashSet.java, line 161
4   java.util.concurrent.ThreadPoolExecutor.interruptIdleWorkers    ThreadPoolExecutor.java, line 755
5   java.util.concurrent.ThreadPoolExecutor.interruptIdleWorkers    ThreadPoolExecutor.java, line 778
6   java.util.concurrent.ThreadPoolExecutor.shutdown    ThreadPoolExecutor.java, line 1357
7   java.util.concurrent.ThreadPoolExecutor.finalize    ThreadPoolExecutor.java, line 1443
8   java.lang.Daemons$FinalizerDaemon.doFinalize    Daemons.java, line 187
9   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
10  java.lang.Thread.run

4

1   com.android.internal.os.BinderInternal$GcWatcher.finalize   BinderInternal.java, line 47
2   java.lang.Daemons$FinalizerDaemon.doFinalize    Daemons.java, line 187
3   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
4   java.lang.Thread.run

2
걱정하지 마세요. bugzilla.mozilla.org/show_bug.cgi?id=864102 또한 앱에 영향을 미치고 있음을 확인할 수 있습니다. Google Play 서비스 문제와 같은 냄새입니다.
eveliotc

오류가 발생한 코드 줄은 2013 년 6 월 5 일에 릴리스 된 버전 4.3_r1을 도입했습니다. 그 이후로 문제가 발생할 수 있습니다.
edubriguenti

안드로이드 버전 4.2.2는 또한이 예외를 던지기 시작했기 때문에 소스 인 Google Play 업데이트 일 수 있습니다.
JWqvist

@EvelioTarazona 플레이 서비스를 사용하지 않는 일부 앱에서 사용 가능
ligi

@ligi 그것은 당신을 위해 동일한 스택 추적입니까?
eveliotc

답변:


220

전체 공개 -저는 TLV DroidCon에서 언급 한 이야기의 저자입니다.

여러 Android 응용 프로그램에서이 문제를 검토하고 문제를 겪은 다른 개발자와 논의 할 기회가있었습니다. 우리 모두 같은 시점에이 문제를 피할 수는 없으며 최소화해야합니다.

이 예외가 발생하는 이유와 가능한 원인에 대해 더 잘 이해하기 위해 Android 가비지 콜렉터 코드의 기본 구현을 자세히 살펴 보았습니다. 실험하는 동안 가능한 근본 원인을 발견했습니다.

문제의 근본 원인은 장치가 잠시 "휴면 상태로 전환"된 시점에 있습니다. 즉, OS는 대부분의 사용자 랜드 프로세스를 잠시 중지하고 화면을 끄고 CPU주기를 줄임으로써 배터리 소비를 줄이기로 결정했음을 의미합니다. 등이 수행되는 방식은 프로세스가 실행 중 일시 중지되는 Linux 시스템 수준입니다. 이는 정상적인 응용 프로그램 실행 중에 언제든지 발생할 수 있지만 컨텍스트 전환이 커널 수준에서 수행되므로 기본 시스템 호출에서 중지됩니다. Dalvik GC가 이야기에 참여하는 곳입니다.

Dalvik GC 코드 (AOSP 사이트의 Dalvik 프로젝트에서 구현 된)는 복잡한 코드가 아닙니다. 기본 작동 방식은 DroidCon 슬라이드에서 다룹니다. 내가 다루지 않은 것은 기본 GC 루프입니다. 수집기가 마무리하고 파괴 할 객체 목록이있는 시점입니다. 베이스의 루프 로직은 다음과 같이 단순화 될 수 있습니다.

  1. 가지고 starting_timestamp,
  2. 해제 할 오브젝트 목록에서 오브젝트를 제거하십시오.
  3. 릴리즈 객체- 필요한 경우 finalize()네이티브를 호출 destroy()합니다.
  4. 가지고 end_timestamp,
  5. 계산 ( end_timestamp - starting_timestamp)하고 하드 코딩 된 시간 초과 값인 10 초와 비교
  6. 시간 초과에 도달 java.util.concurrent.TimeoutException하면 프로세스를 중단하고 종료 하십시오.

이제 다음 시나리오를 고려하십시오.

응용 프로그램은 그 일을 수행합니다.

이것은 사용자 용 응용 프로그램이 아니며 백그라운드에서 실행됩니다.

이 백그라운드 작업 동안 개체를 생성하고 사용하며 메모리를 해제하기 위해 수집해야합니다.

응용 프로그램은 WakeLock을 방해하지 않습니다. 배터리에 악영향을 미쳐 불필요한 것으로 보입니다.

이는 애플리케이션이 때때로 GC를 호출 함을 의미합니다.

일반적으로 GC 실행은 장애없이 완료됩니다.

때때로 (거의 드물게) 시스템은 GC 실행 도중에 휴면을 결정합니다.

응용 프로그램을 충분히 오래 실행하고 Dalvik 메모리 로그를 면밀히 모니터링하면 이런 일이 발생합니다.

이제 기본 GC 루프의 타임 스탬프 로직을 고려하십시오. 장치가 실행을 시작 하고을 수행하고 시스템 객체 start_stampdestroy()기본 호출에서 절전 모드로 전환 할 수 있습니다.

깨어나서 달리기를 재개하면 destroy()의지가 끝나고 다음 end_stampdestroy()전화에 걸린 시간 + 수면 시간이됩니다.

수면 시간이 길면 (10 초 이상) java.util.concurrent.TimeoutException던질 것입니다.

나는 모니터링 파이썬 스크립트에서 생성 된 그래프에서 이것을 보았습니다. 내 자신의 모니터링 된 앱뿐만 아니라 Android 시스템 응용 프로그램 용.

충분한 로그를 수집하면 결국 볼 수 있습니다.

결론 :

문제를 피할 수 없습니다. 앱이 백그라운드에서 실행되면 문제가 발생합니다.

WakeLock을 사용하여 완화하고 장치가 절전 모드로 전환되는 것을 방지 할 수는 있지만 완전히 다른 이야기와 새로운 두통, 또 다른 단점이있을 수 있습니다.

GC 통화를 줄이면 문제를 최소화 할 수 있습니다. 시나리오의 가능성이 줄어 듭니다 (슬라이드에 팁이 있음).

아직 새로운 세대 압축 기능을 자랑하거나 Android Lollipop에서 실험을 수행 한 Dalvik 2 (일명 ART) GC 코드를 살펴볼 기회가 없었습니다.

2015 년 7 월 5 일 추가됨 :

이 충돌 유형에 대한 충돌 보고서 집계를 검토 한 후 Android OS 버전 5.0 이상의 ART (Lollipop with ART)의 충돌은이 충돌 유형의 0.5 % 만 차지하는 것으로 보입니다. 이는 ART GC 변경으로 인해 이러한 충돌 빈도가 감소했음을 의미합니다.

2016 년 6 월 1 일 추가됨 :

Android 프로젝트에서 GC가 Dalvik 2.0 (일명 ART)에서 작동하는 방식에 대한 많은 정보를 추가 한 것 같습니다.

ART 가비지 콜렉션 디버깅 -여기에서 읽을 수 있습니다 .

또한 앱의 GC 동작에 대한 정보를 얻는 도구에 대해서도 설명합니다.

SIGQUIT를 앱 프로세스로 보내면 본질적으로 ANR이 발생하고 분석을 위해 애플리케이션 상태를 로그 파일로 덤프합니다.


필자의 경우 백그라운드에서 실행중인 코드 / 시간을 줄일 수있는 방법을 찾아이를 완화하려고합니다. 주제에 대한 연구에 감사드립니다.
parkerfath

앱에서 수행 된 백그라운드 처리를 제거하면 문제를 줄이는 데 크게 도움이됩니다.
oba

가치가있는 것은 여전히 ​​마시 멜로 (6.0.1)에서 발생합니다. 즉, 나는이 오류를 한 번만 받았습니다. 따라서 큰 문제는 아닌 것 같습니다. 철저한 설명 감사합니다.
Knossos

얼마 후, OS에서이 문제를 해결하는 것은 매우 문제가 있으며 Google과 OEM 간의 협력이 필요하다는 뚜렷한 인상을 받았습니다. 나는 이것이 곧 고쳐질 것으로 기대하지 않는다.
oba

wakelock을 사용하고 있지만 Android 4.4.2에서 여전히이 문제가 발생했습니다. 내 앱에는 백그라운드 작업이 있지만 주로 충전 케이블을 장착하는 동안 하루 종일 작동하도록 설계되었습니다. 이 문제를 완화 할 수있는 다른 방법이 있습니까?
Orcun Sevsay 8

74

우리는 Crashlytics를 사용하여 앱 전체에서 지속적으로 이것을보고 있습니다. 충돌은 일반적으로 플랫폼 코드에서 발생합니다. 작은 샘플링 :

10 초 후 android.database.CursorWindow.finalize () 시간이 초과되었습니다

10 초 후에 java.util.regex.Matcher.finalize () 시간이 초과되었습니다.

android.graphics.Bitmap $ BitmapFinalizer.finalize ()가 10 초 후에 시간 초과되었습니다

10 초 후에 org.apache.http.impl.conn.SingleClientConnManager.finalize ()가 시간 초과되었습니다

10 초 후에 java.util.concurrent.ThreadPoolExecutor.finalize () 시간이 초과되었습니다.

10 초 후 android.os.BinderProxy.finalize () 시간이 초과되었습니다

10 초 후에 android.graphics.Path.finalize () 시간이 초과되었습니다

이 문제가 발생하는 장치는 삼성이 제조 한 압도적으로 (단독은 아님) 장치입니다. 이는 대부분의 사용자가 삼성 기기를 사용하고 있음을 의미 할 수 있습니다. 또는 삼성 기기에 문제가있을 수 있습니다. 확실하지 않습니다.

이것이 실제로 귀하의 질문에 대답하지는 않지만 이것이 매우 일반적이며 응용 프로그램에 국한되지 않는다는 것을 강조하고 싶었습니다.


16
Android 5.0.1 버전에서도 발생하며 Samsung 장치로 제한되지 않는 것 같습니다. Nexus 6에서 발생했습니다.
Shobhit Puri

4
나는 샤오 미에서 제조 장치와 안드로이드 4.4.4에서이 문제를 가지고
Paresh Dudhat

우리는 삼성 태블릿에서 이러한 충돌의 대부분을보고 있다는 점에서 차임하고 싶었습니다. 태블릿이 백그라운드 앱을 처리하는 방식과 관련하여 삼성이 어떻게 다른지 잘 모르겠습니다.
FriendlyMikhail

1
안드로이드 4.4.4 에서이 문제가 있습니다. HUAWEI에서 제조 한 장치.
Rameshbabu

1
android 5.0.2 Samsung 장치에서 누출 카나리아 라이브러리를 사용하면 앱이 다운됩니다. 라이브러리 초기화를 비활성화하면 앱이 정상적으로 작동합니다.
vanomart

15

이 문제에 대한 슬라이드를 발견했습니다.

http://de.slideshare.net/DroidConTLV/android-crash-analysis-and-the-dalvik-garbage-collector-tools-and-tips

이 슬라이드에서 저자는 많은 객체 또는 거대한 객체가 힙에있는 경우 GC에 문제가있는 것 같습니다. 슬라이드에는 샘플 앱에 대한 참조와이 문제를 분석하기위한 Python 스크립트도 포함되어 있습니다.

https://github.com/oba2cat3/GCTest

https://github.com/oba2cat3/logcat2memorygraph

또한이 쪽의 의견 # 3에서 힌트를 찾았습니다 : https://code.google.com/p/android/issues/detail?id=53418#c3


7

를 중지하여 문제를 해결했습니다 FinalizerWatchdogDaemon.

public static void fix() {
    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();
    }
}

다음과 같이 응용 프로그램 수명주기에서 메소드를 호출 할 수 있습니다 attachBaseContext(). 같은 이유로, 당신은 또한 문제를 해결하기 위해 전화의 제조를 지정할 수 있습니다, 그것은 당신에게 달려 있습니다.


우리를 위해 작동하지 않습니다 이유를 이해할 수 없습니다. 코드는 예외없이 완료되지만 Crashlytics 보고서 및 Google Play Console에서 이러한 문제가 계속 발생합니다.
Anton Breusov

5

10 초 후 브로드 캐스트 리시버 제한 시간. 브로드 캐스트 수신기에서 비동기 호출 (잘못된)을 수행하면 실제로 4.3이 감지 할 수 있습니다.


3
그것을 감지하고 그것에 대해 충분히 말하지 않는 것 같습니다. 어떤 방송이 좋을지 알려주십시오.
Aaron T Harris

내가 틀렸다면 용서하지만 브로드 캐스트 수신기 시간 초과로 인해이 특정 충돌이 발생하지 않는다고 생각합니다. 10 초 한도를 피하는 것이 좋지만 요청자가하는 것과는 다른 문제입니다.
parkerfath

뇌에 10 초 밖에 없어요 충돌을 일으킨 경우 developer.android.com/training/articles/perf-anr.html IDK
danny117

당신의 요점은 견고하고 좋은 연습입니다. 그러나 원본 포스터에는 특정 장치 세트에 대한 특정 질문이 있습니다. 이 게시물의 다른 시청자에게 Christopher의 답변과 oba의 답변이 동일한 증상 (Samsung 기기 (
Ep

나는 장치 제조를 비난하기 위해 여기에 있지 않다.
danny117

5

이 문제를 해결하기위한 didi의 효과적인 해결책은 다음과 같습니다.이 버그는 매우 흔하고 원인을 찾기가 어렵 기 때문에 시스템 문제처럼 보입니다. 직접 무시할 수없는 이유는 무엇입니까? 물론 무시할 수 있습니다. 샘플 코드는 다음과 같습니다.

final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler = 
        Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        if (t.getName().equals("FinalizerWatchdogDaemon") && e instanceof TimeoutException) {
        } else {
            defaultUncaughtExceptionHandler.uncaughtException(t, e);
        }
    }
});

응용 프로그램은 특수한 기본 포착되지 않은 예외 처리기를 설정하여 시스템이 제공 한 기본 동작을 이미 수락 한 스레드에 대해 포착되지 않은 예외가 처리되는 방식을 변경할 수 있습니다. 잡히지 않은 TimeoutException스레드에서 잡히지 않을 때FinalizerWatchdogDaemon 않으면이 특수 핸들러는 핸들러 체인을 차단하고 시스템 핸들러는 호출되지 않으므로 충돌을 피할 수 있습니다.

연습을 통해 다른 나쁜 영향은 발견되지 않았습니다. GC 시스템은 여전히 ​​작동하고 있으며 CPU 사용량이 감소함에 따라 시간 초과가 완화됩니다.

자세한 내용은 https://mp.weixin.qq.com/s/uFcFYO2GtWWiblotem2bGg를 참조하십시오.


4

항상 사실 중 하나는이 시점에서 장치가 일부 메모리에 대해 질식 할 것입니다 (일반적으로 GC가 트리거되는 이유).

이전에 거의 모든 저자가 언급했듯이이 문제는 앱이 백그라운드에있는 동안 Android에서 GC를 실행하려고 할 때 발생합니다. 우리가 관찰 한 대부분의 경우, 사용자는 화면을 잠 가서 앱을 일시 중지했습니다. 또한 응용 프로그램 어딘가에서 메모리 누수가 발생했거나 장치가 이미로드되어 있음을 나타냅니다. 따라서 그것을 최소화하는 유일한 합법적 인 방법은 다음과 같습니다.

  • 메모리 누수가 없는지 확인하고
  • 일반적으로 앱의 메모리 사용량을 줄입니다.

1
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();
}

절전 시간이 100 초를 초과하는 경우 문제가 해결되지 않습니다. 왜 MAX_INT로 설정하지 않습니까?
oba

예, 그냥 예를
들어요

1
일정한 인라인으로 인해 작동하지 않아야합니다. 필드 값을 변경해도 발신자에게 인라인 된 값에는 영향을 미치지 않습니다.
hqzxzwb

0

finalizeQueue가 너무 길 수 있습니다

Java가 사용자가 finalizedQueue 길이를 명시 적으로 줄일 수 있도록 GC.SuppressFinalize ()GC.ReRegisterForFinalize () 가 필요할 수 있다고 생각합니다.

JVM의 소스 코드가 사용 가능한 경우 Android ROM 메이커와 같은 이러한 메소드를 직접 구현할 수 있습니다.


0

Android 런타임 버그처럼 보입니다. 별도의 스레드에서 실행되고 스택 추적의 현재 프레임에없는 경우 객체에서 finalize () 메서드를 호출하는 종료자가있는 것 같습니다. 예를 들어 다음 코드 (이 문제를 확인하기 위해 생성됨)는 충돌로 끝났습니다.

finalize 메소드에서 무언가를하는 커서를 가져 봅시다 (예 : SqlCipher 커서, 현재 사용중인 데이터베이스에 잠그는 close ()를 수행하십시오)

private static class MyCur extends MatrixCursor {


    public MyCur(String[] columnNames) {
        super(columnNames);
    }

    @Override
    protected void finalize() {
        super.finalize();

        try {
            for (int i = 0; i < 1000; i++)
                Thread.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

그리고 커서를 연 상태에서 오래 실행되는 것들이 있습니다.

for (int i = 0; i < 7; i++) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                MyCur cur = null;
                try {
                    cur = new MyCur(new String[]{});
                    longRun();
                } finally {
                    cur.close();
                }
            }

            private void longRun() {
                try {
                    for (int i = 0; i < 1000; i++)
                        Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

다음과 같은 오류가 발생합니다.

FATAL EXCEPTION: FinalizerWatchdogDaemon
                                                                        Process: la.la.land, PID: 29206
                                                                        java.util.concurrent.TimeoutException: MyCur.finalize() timed out after 10 seconds
                                                                            at java.lang.Thread.sleep(Native Method)
                                                                            at java.lang.Thread.sleep(Thread.java:371)
                                                                            at java.lang.Thread.sleep(Thread.java:313)
                                                                            at MyCur.finalize(MessageList.java:1791)
                                                                            at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:222)
                                                                            at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:209)
                                                                            at java.lang.Thread.run(Thread.java:762)

SqlCipher를 사용한 프로덕션 변형은 매우 유사합니다.

12-21 15:40:31.668: E/EH(32131): android.content.ContentResolver$CursorWrapperInner.finalize() timed out after 10 seconds
12-21 15:40:31.668: E/EH(32131): java.util.concurrent.TimeoutException: android.content.ContentResolver$CursorWrapperInner.finalize() timed out after 10 seconds
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Object.wait(Native Method)
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Thread.parkFor$(Thread.java:2128)
12-21 15:40:31.668: E/EH(32131): 	at sun.misc.Unsafe.park(Unsafe.java:325)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:161)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:840)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:873)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1197)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:200)
12-21 15:40:31.668: E/EH(32131): 	at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:262)
12-21 15:40:31.668: E/EH(32131): 	at net.sqlcipher.database.SQLiteDatabase.lock(SourceFile:518)
12-21 15:40:31.668: E/EH(32131): 	at net.sqlcipher.database.SQLiteProgram.close(SourceFile:294)
12-21 15:40:31.668: E/EH(32131): 	at net.sqlcipher.database.SQLiteQuery.close(SourceFile:136)
12-21 15:40:31.668: E/EH(32131): 	at net.sqlcipher.database.SQLiteCursor.close(SourceFile:510)
12-21 15:40:31.668: E/EH(32131): 	at android.database.CursorWrapper.close(CursorWrapper.java:50)
12-21 15:40:31.668: E/EH(32131): 	at android.database.CursorWrapper.close(CursorWrapper.java:50)
12-21 15:40:31.668: E/EH(32131): 	at android.content.ContentResolver$CursorWrapperInner.close(ContentResolver.java:2746)
12-21 15:40:31.668: E/EH(32131): 	at android.content.ContentResolver$CursorWrapperInner.finalize(ContentResolver.java:2757)
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:222)
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:209)
12-21 15:40:31.668: E/EH(32131): 	at java.lang.Thread.run(Thread.java:762)

재개 : 커서를 최대한 빨리 닫습니다. 적어도 문제가 발생한 Android 7이 설치된 Samsung S8에서.


0

작성하는 클래스 (예 : Android의 일부가 아님)의 경우 충돌을 완전히 피할 수 있습니다.

구현하는 모든 클래스는 finalize()@oba에서 설명한 것처럼 피할 수없는 충돌 가능성이 있습니다. 따라서 마무리를 사용하여 정리를 수행하는 대신PhantomReferenceQueue .

예를 들어 React Native의 구현을 확인하십시오 : https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/jni/DestructorThread.java

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.