我的应用程序使用sqlcipher数据库。它使用游标加载器从db
查询数据我遇到了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)
我一直在尝试调试此问题,但不知道从哪里开始
有人可以帮助我
答案 0 :(得分:0)
基于日志,我能想到的唯一可能触发ANR的原因是:
据我所知,通常在Java中,每个线程都与2个组件相关联。一个是程序计数器,另一个是垃圾收集器。所以每个线程都会有一个gc监视器发生。
等待(java.lang.VMThread)由tid = 1(主要)持有
VMThreads理想地用于处理监视gc的这个方面,几乎是并行的。所以我能想到的是,对于你的场景,SQLiteDatabase正试图获取一个锁,但是因为VMThread正在持有锁,尚未释放(可能是由于某些主要的GC操作),因此等待vmthread释放锁。
您可能想要检查记录了gc活动的主日志转储,这可能会让您更好地了解为什么gc占用此线程的CPU时间太多,然后应用程序分析可能会有所帮助。 检查。