http://infinitesproutingthoughts.wordpress.com/2013/06/21/deciphering-android-garbage-collection-gc-logs/
Android dalvikVM (DVM) provides own Thread wrapper on top of native threads(Linux posix threads).
Below Excerpts are explained and understood from Android Source code location “dalvik/vm/Thread.h/.cpp”
A Java thread can be any of below status:
- UNDEFINED
- ZOMBIE : thread got terminated.
- RUNNING:
- TIMED_WAIT:
- WAIT
- INITIALIZING
- STARTING
- NATIVE
- VMWAIT
- SUSPENDED
RUNNING and NATIVE:
Two thread states are tricky to understand RUNNING and NATIVE, RUNNING corresponds when thread is running in dalvikvm(Dvm) and NATIVE when same thread enters in JNI native methods. As per Dalvik JNI implementation(dalvik/vm/Jni.cpp) ”All JNI methods must start by changing their thread status to THREAD_RUNNING, and finish by changing it back to THREAD_NATIVE before returning to native code”, i.e whenever a native call invokes a JNI method, the Thread Status is set to RUNNING and when it comes back to native it is reset to NATIVE, and this achieved by C++ class “ScopedJniThreadState” which calls dvmChangeStatus(mSelf, THREAD_RUNNING); in it’s constructor and dvmChangeStatus(mSelf, THREAD_NATIVE); in Destructor
SUSPENDED and ANR stack dump.
A java thread can be placed in SUSPENDED state mostly due to GC(CONCURRENT) collection and debugger(DDMS), when any of these operations are performed all thread except debugger thread(JDWP) and SignalCacther are suspended,
In case of DVM Singal catcher(A per process global signal catcher) when received any signal like SIGQUIT (3) sent from ActivityManagerService due to ANR/slow operation, it calls dvmSuspendAllThreads(), which suspend all java threads(not native) to make them wait on gDvm.threadSuspendCountCond, once all threads stack is dumped , it resumes all the suspended thread by broadcasting on waited condition.
A Catch: Java thread in NATIVE state doesn’t get affected by above suspended operation hence on ANR dump only Java Stack trace gets dumped except binder threads. So on ANR dump, if main thread sate = NATIVE, main thread was executing some native method, and if = SUSPENDED, it was in java method and got suspended to dump stack traces.