2013-02-25 67 views
6

我們正在研究Android果凍豆項目。我們的平臺是基於arm的,內核版本是3.1.10。在我們的開發過程中,我們發現應用程序崩潰發生在達爾維克的可能性非常低。基於以下回溯日誌,在垃圾回收功能期間出現崩潰。在使用addr2line分析pc地址後,我們發現obj-> clazz在發生問題時成爲違規地址。Android dalvik垃圾收集可能會崩潰?

代碼流程是: (dvmHeapScanMarkedObjects - > processMarkStack-> scanObject - >(IS_CLASS_FLAG_SET(obj-> clazz所CLASS_ISARRAY)))

現在我們被困在這兒了,不能找到一種方法解決它。所以我們需要更多的建議和幫助。

有沒有人知道這個問題或如何檢查它?

如下回溯日誌:

F/libc ( 912): Fatal signal 11 (SIGSEGV) at 0x00000025 (code=1), thread 912 (zygote) 
I/DEBUG ( 910): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***I/DEBUG ( 910): Revision: '32' 
I/DEBUG ( 910): pid: 912, tid: 912, name: zygote >>> zygote <<< 
I/DEBUG ( 910): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000025 
I/DEBUG ( 910):  r0 00000005 r1 41246df0 r2 44208890 r3 412471e8 
I/DEBUG ( 910):  r4 40e3c1b8 r5 412569c0 r6 40e3c1b8 r7 41246df0 
I/DEBUG ( 910):  r8 0000154c r9 00000000 sl 000798e4 fp 7fffffff 
I/DEBUG ( 910):  ip 51b2c044 sp bee580c0 lr 40dc5b88 pc 40dc598c cpsr 80000010 
I/DEBUG ( 910):  d0 6e69737275636567 d1 6f7268540000fa2e 
I/DEBUG ( 910):  d2 573752085737512e d3 573752785737522e 
I/DEBUG ( 910):  d4 5737527857375240 d5 573841a0573752b0 
I/DEBUG ( 910):  d6 00010000573841d8 d7 000000614ac3ff00 
I/DEBUG ( 910):  d8 0000000000000000 d9 0000000000000000 
I/DEBUG ( 910):  d10 0000000000000000 d11 0000000000000000 
I/DEBUG ( 910):  d12 0000000000000000 d13 0000000000000000 
I/DEBUG ( 910):  d14 0000000000000000 d15 0000000000000000 
I/DEBUG ( 910):  d16 0000000000019a5c d17 0000000000019a5c 
I/DEBUG ( 910):  d18 0000000000000000 d19 3fe8000000000000 
I/DEBUG ( 910):  d20 0000000000000000 d21 0000000000000000 
I/DEBUG ( 910):  d22 0000000000000000 d23 0000000000000000 
I/DEBUG ( 910):  d24 0000000000000000 d25 0000000000000000 
I/DEBUG ( 910):  d26 0000000000000000 d27 0000000000000000 
I/DEBUG ( 910):  d28 0000000000000000 d29 0000000000000000 
I/DEBUG ( 910):  d30 0000000000000000 d31 0000000000000000 
I/DEBUG ( 910):  scr 60000010 
I/DEBUG ( 910): 
I/DEBUG ( 910): backtrace: 
I/DEBUG ( 910):  #00 pc 0003798c /system/lib/libdvm.so 
I/DEBUG ( 910):  #01 pc 00037b84 /system/lib/libdvm.so 
I/DEBUG ( 910):  #02 pc 000298c0 /system/lib/libdvm.so (dvmCollectGarbageInternal(GcSpec const*)+196) 
I/DEBUG ( 910):  #03 pc 0002a0bc /system/lib/libdvm.so (dvmMalloc(unsigned int, int)+152) 
I/DEBUG ( 910):  #04 pc 00054f57 /system/lib/libdvm.so (dvmAllocObject+6) 
I/DEBUG ( 910):  #05 pc 0001ecb0 /system/lib/libdvm.so 
I/DEBUG ( 910):  #06 pc 0002b754 /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184) 
I/DEBUG ( 910):  #07 pc 0005fe09 /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+272) 
I/DEBUG ( 910):  #08 pc 0005fe33 /system/lib/libdvm.so (dvmCallMethod(Thread*, Method const*, Object*, JValue*, ...)+20) 
I/DEBUG ( 910):  #09 pc 000539c9 /system/lib/libdvm.so (dvmPrepMainThread()+188) 
I/DEBUG ( 910):  #10 pc 00047c65 /system/lib/libdvm.so (dvmStartup(int, char const* const*, bool, _JNIEnv*)+1108) 
I/DEBUG ( 910):  #11 pc 0004dd8d /system/lib/libdvm.so (JNI_CreateJavaVM+544) 
I/DEBUG ( 910):  #12 pc 00047227 /system/lib/libandroid_runtime.so (android::AndroidRuntime::startVm(_JavaVM**, _JNIEnv**)+1626) 
I/DEBUG ( 910):  #13 pc 000476bd /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+176) 
I/DEBUG ( 910):  #14 pc 00000db7 /system/bin/app_process 
I/DEBUG ( 910): 
I/DEBUG ( 910): stack: 
I/DEBUG ( 910):   bee58080 00000000 
I/DEBUG ( 910):   bee58084 40dc599c /system/lib/libdvm.so 
I/DEBUG ( 910):   bee58088 41247f38 /dev/ashmem/dalvik-heap (deleted) 
I/DEBUG ( 910):   bee5808c 000003f0 
I/DEBUG ( 910):   bee58090 000000fd 
I/DEBUG ( 910):   bee58094 00000000 
I/DEBUG ( 910):   bee58098 41246ebc [heap] 
I/DEBUG ( 910):   bee5809c 40db7578 /system/lib/libdvm.so (dvmHeapBitmapScanWalk(HeapBitmap*, void (*)(Object*, void*, void*), void*)+128) 
I/DEBUG ( 910):   bee580a0 40dc5b9c /system/lib/libdvm.so 
I/DEBUG ( 910):   bee580a4 41247f38 /dev/ashmem/dalvik-heap (deleted) 
I/DEBUG ( 910):   bee580a8 40e3c1b8 /system/lib/libdvm.so 
I/DEBUG ( 910):   bee580ac 412569a0 /dev/ashmem/dalvik-heap (deleted) 
I/DEBUG ( 910):   bee580b0 40e3c1b8 /system/lib/libdvm.so 
I/DEBUG ( 910):   bee580b4 41246df0 [heap] 
I/DEBUG ( 910):   bee580b8 df0027ad 
I/DEBUG ( 910):   bee580bc 00000000 
I/DEBUG ( 910):  #00 bee580c0 51b2c048 /dev/ashmem/dalvik-mark-stack (deleted) 
I/DEBUG ( 910):   bee580c4 41246df0 [heap] 
I/DEBUG ( 910):   bee580c8 41246dd8 [heap] 
I/DEBUG ( 910):   bee580cc 40e3c1b8 /system/lib/libdvm.so 
I/DEBUG ( 910):   bee580d0 00000001 
I/DEBUG ( 910):   bee580d4 40dc5b88 /system/lib/libdvm.so 
I/DEBUG ( 910):  #01 bee580d8 40e34aa8 /system/lib/libdvm.so 
I/DEBUG ( 910):   bee580dc 40db78c4 /system/lib/libdvm.so (dvmCollectGarbageInternal(GcSpec const*)+200) 
I/DEBUG ( 910):  #02 bee580e0 bee58124 [stack] 
I/DEBUG ( 910):   bee580e4 40df9095 /system/lib/libdvm.so 
I/DEBUG ( 910):   bee580e8 5855879e /data/dalvik-cache/[email protected]@[email protected] 
I/DEBUG ( 910):   bee580ec 40087010 
I/DEBUG ( 910):   bee580f0 5855879e /data/dalvik-cache/[email protected]@[email protected] 
I/DEBUG ( 910):   bee580f4 410be000 /dev/ashmem/dalvik-aux-structure (deleted) 
I/DEBUG ( 910):   bee580f8 00000000 
I/DEBUG ( 910):   bee580fc 00000000 
I/DEBUG ( 910):   bee58100 000006db 
I/DEBUG ( 910):   bee58104 410be000 /dev/ashmem/dalvik-aux-structure (deleted) 
I/DEBUG ( 910):   bee58108 00000000 
I/DEBUG ( 910):   bee5810c 410f55cc /dev/ashmem/dalvik-aux-structure (deleted) 
I/DEBUG ( 910):   bee58110 412569d8 /dev/ashmem/dalvik-heap (deleted) 
I/DEBUG ( 910):   bee58114 41248338 /dev/ashmem/dalvik-heap (deleted) 
I/DEBUG ( 910):   bee58118 41248338 /dev/ashmem/dalvik-heap (deleted) 
I/DEBUG ( 910):   bee5811c 40e3c1b8 /system/lib/libdvm.so 
I/DEBUG ( 910):   ........ ........ 
+2

您可以嘗試在Android平臺組(https://groups.google.com/forum/?fromgroups=#!forum/android-platform)中發帖。另外,它是否會在除zygote之外的進程中崩潰,並且您的程序是否具有本地部分?如果是這樣,您可能有一個導致堆損壞的錯誤 - 請參閱崩潰報告中的討論以獲取一些建議:https://code.google.com/p/android/issues/detail?id=10574&can=1&q=scanObject&colspec=ID %20Type%20Status%20Owner%20Summary%20Stars。 – 2013-02-25 17:19:02

+1

FWIW,那個堆棧跟蹤通常表示託管堆(即GC管理的「Dalvik堆」,與'malloc'堆相對)已被破壞。 'scanObject'碰巧是在GC期間嘗試追逐對象的類指針的第一件事。大多數情況下,原因是一些原生代碼在內存中塗寫不應該。 – fadden 2013-03-12 16:52:00

+0

我也遇到了同樣的問題。你有沒有找到解決辦法? – 2013-12-04 13:16:26

回答

3

啊,我花了相當長的時間的情況來分析,我有一個類似的問題。希望我的分析能幫助你。

與我的問題,問題是由於編譯器的內存重新排序。在達爾維克幾個線程共享公共內存ASHMEM。由於編譯器進行內存重新排序以優化,此ASHMEM可能已損壞。 爲了避免在特定點執行內存重新排序,請執行內存屏障(AKA membar)。 Check this link for executing membar

只要把一個存儲器屏障ANDROID_MEMBAR_BARRIER()對象分配之前和對象釋放在垃圾收集內存分配器(如達爾維克/ VM /分配/ alloc.cpp)和class.cpp,array.cpp和proxy.cpp在達爾維克android源代碼目錄。這應該可以解決問題。

有關記憶障礙請檢查更多資料以下鏈接

memory barrier

example

白皮書Hardware View of Memory Barriers

+2

如果您要修改堆,則需要持有堆鎖,在這種情況下,會爲您提供內存屏障。如果您沒有持有堆鎖,那麼世界上所有的障礙都無法爲您解決併發訪問問題。有關Android內存障礙和一般SMP問題的更多信息,請參閱http://developer.android.com/training/articles/smp.html。 – fadden 2013-03-12 16:58:01

0

你的意思是把ANDROID_MEMBAR_FULL()所有dvmMalloc後面就像代碼下列? 垃圾收集流程中的內存釋放功能在哪裏?謝謝

static bool createInitialClasses() { 
    /* 
    * Initialize the class Class. This has to be done specially, particularly 
    * because it is an instance of itself. 
    */ 
    ClassObject* clazz = (ClassObject*) 
     dvmMalloc(classObjectSize(CLASS_SFIELD_SLOTS), ALLOC_NON_MOVING); 
    ANDROID_MEMBAR_FULL(); 
+0

引入額外的內存屏障是不必要的。 「dvmMalloc」所做的第一件事就是鎖定堆,而互斥鎖根據定義包含內存障礙。 – fadden 2013-03-12 16:55:59