쓰레드 덤프는 프로세스에서 실행중인 쓰레드들의 스냅샷입니다. 쓰레드 덤프를 통해서 덤프시점에 현재 어떤 쓰레드들이 있는지, 쓰레드들의 상태는 어떤지, 쓰레드가 어떤 메소드를 실행하며 지나왔고 어떤 메소드를 실행중인지 파악할 수 있습니다.

1. DDMS 쓰레드 뷰
안드로이드는 DDMS를 통해서 쓰레드 스택을 쉽게 분석할 수 있게 지원합니다.

(1) DDMS에서 프로세스를 선택후 Update Threads 아이콘을 클릭합니다. 
(2) 오른편 Threads 탭에 선택된 프로세스의 쓰레드 목록이 나타납니다.  
(3) 쓰레드를 한개 선택하고 Refresh 버튼을 누르면 그 순간의 쓰레드스택(쓰레드가 실행한 객체 메소드) 정보가 나타납니다.


Threads 목록의 각 컬럼에 대한 설명은 다음과 같습니다.
  • ID : VM 내의 쓰레드 ID. DVM의 경우 3부터 시작하는 홀수. 앞의 별표는 데몬(daemon) 쓰레드.
  • Tid : 리눅스 쓰레드 ID. main 쓰레드의 경우 프로세스 ID와 일치.
  • Status : 쓰레드 상태 
running - executing application code(실행중)
sleeping - called Thread.sleep() 
monitor - waiting to acquire a monitor lock(다른 쓰레드가 작업을 마치기를 기다리는 중)
wait - in Object.wait() 
native - executing native code 
vmwait - waiting on a VM resource 
zombie - thread is in the process of dying 
init - thread is initializing (you shouldn't see this) 
starting - thread is about to start (you shouldn't see this either) 

  • utime : 사용자 코드 누적 실행시간. cumulative time spent executing user code, in "jiffies" (usually 10ms). 
  • stime : 시스템 코드 누적 실행시간. cumulative time spent executing system code, in "jiffies" (usually 10ms). 
  • Name : 쓰레드 이름

의미있는 스택 트레이스 정보를 보기 위해서는, 단말의 기능을 사용하면서 순간을 잘 포착하여 Refresh 버튼을 눌러야 트레이스를 제대로 볼 수 있습니다. 때를 놓치면 이미 실이 지나가고 난 뒤의 고요한 트레이스만 보이게 됩니다. ^^
애플리케이션이 응답 없음 상태(ANR)일 때 Refresh 버튼을 눌러, 도대체 쓰레드가 현재 어떤 메소드를 실행 중이길래 반응이 없는 건지 알 수 있을 것으로 보입니다. 또한 락(lock)이 걸렸을 때 이것이 쓰레드 경합(monitor 상태의 쓰레드들)에 의한 문제인지 파악할 수 있을 것으로 보입니다. (그러나 2경우 모두 아직 이런 식으로는 확인 못해봤습니다.-.-; )

2. /data/anr/traces.txt
애플리케이션에 에러가 발생해서 프로세스가 죽게 되면 달빅 VM은 보통의 JVM처럼 자동으로 쓰레드덤프(javacore) 파일을 떨궈줍니다.  "/data/anr/traces.txt" 파일이 그것입니다. 
아래는 애플리케이션 에러로 애플리케이션이 중지되는 시점의 로그입니다. 맨 아랫줄을 보시면 스택트레이스가 "/data/anr/traces.txt" 파일에 쓰여진다는 정보를 볼 수 있습니다.


경우에 따라서는 애플리케이션 프로세스가 "/data/anr/traces.txt" 파일에 쓰기 권한이 없어서(permission denied) traces.txt에 기록을 못할 수도 있습니다. 하지만 꼭 traces.txt가 아니더라도 위에 나오듯이 로그캣에 친절하게 Exception 스택 트레이스 정보가 나오기 때문에 에러 분석에는 큰 문제가 없을 것입니다.

쓰레드 덤프는 사용자가 직접 kill -3 <PROCESS ID> 명령을 날려서 만들 수도 있습니다. ANR이 발생하거나 lock이 걸리면 이렇게 쓰레드덤프를 떠야겠죠. 참고로, /data/anr/traces.txt 파일은 매번 새로 생성되지 않고 기존 파일에 쓰레드 덤프가 누적되어 기록됩니다. 아래는 쓰레드 덤프 파일에 기록된 내용의 예입니다.

----- pid 224 at 2010-02-12 05:41:20 -----
Cmd line: com.example.android.notepad

DALVIK THREADS:
"main" prio=5 tid=3 WAIT
  | group="main" sCount=1 dsCount=0 s=N obj=0x4001b268 self=0xbd00
  | sysTid=224 nice=0 sched=0/0 cgrp=default handle=-1344001384
  at java.lang.Object.wait(Native Method)
  - waiting on <0x14c328> (a android.os.MessageQueue)
  at java.lang.Object.wait(Object.java:288)
  at android.os.MessageQueue.next(MessageQueue.java:148)
... 중략 ...
  at java.lang.reflect.Method.invoke(Method.java:521)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
  at dalvik.system.NativeStart.main(Native Method)

"Binder Thread #1" prio=5 tid=11 NATIVE
  | group="main" sCount=1 dsCount=0 s=N obj=0x43cfb248 self=0x134170
  | sysTid=228 nice=0 sched=0/0 cgrp=default handle=1259984
  at dalvik.system.NativeStart.run(Native Method)

"JDWP" daemon prio=5 tid=9 VMWAIT
... 중략 ...
"Signal Catcher" daemon prio=5 tid=7 RUNNABLE
... 중략 ...
"HeapWorker" daemon prio=5 tid=5 VMWAIT
... 중략 ...
----- end 224 -----

* 일부 내용에 오류가 있을 수 있습니다.
Posted by 에코지오
,