2

我的应用程序使用 sqlcipher 数据库。它使用游标加载器从数据库中查询数据

我遇到了 ANR。请参阅下面的 ANR 跟踪

我在这里试图理解的是,为什么试图关闭光标的主线程会被自身阻塞。这个问题是随机发生的,我还没有想出一个可重现的场景。我怀疑这是否是与 sqlcipher 的游标实现相关的锁定问题。

    "main" prio=5 tid=1 WAIT
    | group="main" sCount=1 dsCount=0 obj=0x415979a0 self=0x4000b010
    | sysTid=9804 nice=0 sched=0/0 cgrp=apps handle=1075102172
    | state=S schedstat=( 0 0 0 ) utm=3670 stm=710 core=1
    at java.lang.Object.wait(Native Method)

waiting on (a java.lang.VMThread) held by tid=1 (main) at
java.lang.Thread.parkFor(Thread.java:1231) at sun.misc.Unsafe.park(Unsafe.java:323) at 
java.util.concurrent.locks.LockSupport.park(LockSupport.java:159) at 
java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:810) at 
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:843) at
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1173) at
java.util.concurrent.locks.ReentrantLock$FairSync.lock(ReentrantLock.java:198) at 
java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:259) at 
net.sqlcipher.database.SQLiteDatabase.lock(SQLiteDatabase.java:460) at 
net.sqlcipher.database.SQLiteProgram.close(SQLiteProgram.java:294) at 
net.sqlcipher.database.SQLiteQuery.close(SQLiteQuery.java:136) at 
net.sqlcipher.database.SQLiteCursor.close(SQLiteCursor.java:510) at
android.database.CursorWrapper.close(CursorWrapper.java:49) at 
android.database.CursorWrapper.close(CursorWrapper.java:49) at 
android.content.ContentResolver$CursorWrapperInner.close(ContentResolver.java:1860) at
android.database.MergeCursor.close(MergeCursor.java:175) at 
android.database.CursorWrapper.close(CursorWrapper.java:49) at 
android.content.CursorLoader.deliverResult(CursorLoader.java:117) at 
android.content.CursorLoader.deliverResult(CursorLoader.java:43)

我一直在尝试调试问题,但不知道从哪里开始

有人可以帮我吗

4

1 回答 1

0

根据日志,我能想到的可能触发 ANR 的唯一原因是:

据我所知,通常在 Java 中每个线程都与 2 个组件相关联。一个是程序计数器,另一个是垃圾收集器。所以每个线程都会有一个 gc 监视器在整个过程中发生。

等待 tid=1 (main) 持有的 (a java.lang.VMThread) 在

VMThreads 理想地用于处理监控 gc 的这一方面,几乎是并行的。因此,对于您的情况,我能想到的是 SQLiteDatabase 正在尝试获取锁但无法获取,因为 VMThread 持有锁,尚未释放(可能是由于某些主要的 GC 操作),因此等待 vmthread 释放锁。

您可能想检查记录了 gc 活动的主日志转储,这可能会让您更好地了解 gc 为何如此占用此线程 CPU 时间,然后应用程序分析可能会有所帮助。检查一下。

于 2013-08-22T10:59:50.447 回答