2013-04-30 20 views
2

我的應用程序使用sqlcipher數據庫。它使用光標加載器從數據庫查詢數據Android主線程在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

基於日誌,我能想到的,可能的唯一原因已經觸發了一個ANR是:

據我所知,通常在Java中每個線程都與2個組件相關聯。一個是程序計數器,另一個是垃圾收集器。所以每個線程都會有一個gc監視器。

VMThreads等待(一個java.lang.VMThread)由TID = 1(主要)保持理想地用於處理監控GC的這個方面,幾乎平行。所以我能想到的,對於你的場景,SQLiteDatabase是試圖獲得一個鎖,但無法執行,因爲VMThread持有鎖,尚未發佈(可能是由於某些主要的GC操作),因此等待vmthread釋放鎖。

您可能想要檢查您的主日誌轉儲,其中包含gc活動記錄,這可能會讓您更好地瞭解爲什麼gc佔用此線程CPU時間,然後應用程序分析可能會有所幫助。 Jus檢查。