๐ฅ ๊ฒฐ๋ก : ํ๋์ Java ํ๋ก์ธ์ค ์์ ์๋ thread๋ค์ ์ ๋ถ ๋ถ๋ฆฌํด์ ํ์ธํ ์ ์๋ค
๋ฐฉ๋ฒ์ ๋ฐ๋ก ์ด๊ฒ:
โ 1. Linux์์ Java ํ๋ก์ธ์ค์ thread๋ฅผ ๋ถ๋ฆฌํด์ ๋ณด๋ ๋ฐฉ๋ฒ
๋ช ๋ น์ด
์:
๊ทธ๋ผ ํ๋์ Java ํ๋ก์ธ์ค(PID=12345) ์์ ์๋ ๋ชจ๋ thread(TID) ๊ฐ ๊ฐ๊ฐ CPU๋ฅผ ์ผ๋ง๋ ์ฐ๋์ง ๋์ต๋๋ค.
์:
- 12347: ํ๋์ TID(thread ID)
- ์ด๊ฒ CPU 280% ๋จน๊ณ ์์ → ๋ฌธ์ ์ฐ๋ ๋
์ฆ, Java ํ ๊ฐ ํ๋ก์ธ์ค ์์ ๊ฐ thread CPU ์ฌ์ฉ๋์ ๋ถ๋ฆฌํด์ ์ ์ ์์.
โ 2. ๋ฌธ์ thread๊ฐ “Java ๋ด๋ถ์์ ์ด๋ค ํจ์”๋ฅผ ๋๊ณ ์๋์ง๋ ํ์ธ ๊ฐ๋ฅ
์ด๊ฑด Java thread dump(jstack)๋ฅผ ์ฌ์ฉํฉ๋๋ค.
Step A. thread ID(TID)๋ฅผ 16์ง์๋ก ๋ณํ
Java thread dump๋ hex ๊ฐ์ผ๋ก thread๋ฅผ ํ์ํจ.
์ถ๋ ฅ ์:
Step B. jstack ์คํ
Step C. thread ID(hex)๋ก ๊ฒ์
๊ทธ๋ผ ์ด๋ ๊ฒ ๋์ต๋๋ค:
์ฌ๊ธฐ์:
- nid=0x303b ← ์ด๊ฒ ๋ฐ๋ก ๋ฌธ์ thread
- process() ํจ์์์ CPU๋ฅผ ๋ง์ด ๋จน๊ณ ์์
- runLoop() ์์์ ๋ฌดํ loop๊ฐ ๋๊ณ ์์ ์ ์์
์ด๋ ๊ฒ ์ ํํ ํจ์ ์ด๋ฆ + ๋ผ์ธ๋ฒํธ๊น์ง ์ ์ ์์ต๋๋ค.
๐ฅ ์ถ๊ฐ: thread ์ด๋ฆ๊น์ง ์ ์ ์์
Java์์๋ thread๋ฅผ ๋ง๋ค ๋ ์ด๋ฆ์ ๋ถ์ด๋ฉด
jstack์์ ์ด๋ ๊ฒ ๋ณด์ ๋๋ค:
์ฆ,
- thread ์ด๋ฆ
- thread ์ํ
- thread call stack
- CPU ์ ์ ์จ
- lock(JVM monitor) ๋ณด์ ์ฌ๋ถ
์ ๋ถ ํ์ธ ๊ฐ๋ฅ.
๐ฅ ์ถ๊ฐ: thread ๋ชฉ๋ก ์ ์ฒด ๋ณด๊ธฐ
๋๋ ์๋์ผ๋ก thread hierarchy ํ์ธ ๊ฐ๋ฅ.
๐ฅ ๊ฒฐ๋ก ์์ฝ
ํ๋์ Java ํ๋ก๊ทธ๋จ์ด๋ผ๋ ๋ด๋ถ thread๋ค์ ๊ฐ๋ณ TID๋ฅผ ๊ฐ์ง๋ฏ๋ก
CPU ์ฌ์ฉ๋, ํจ์ ์์น, thread ์ด๋ฆ ๋ฑ์ ์ ๋ถ ๋ถ๋ฆฌํด์ ํ์ธ ๊ฐ๋ฅํ๋ค.
โ top -H -p PID → thread CPU ์๋ณ
โ printf "%x" TID → hex ๋ณํ
โ jstack PID → thread dump
โ grep hex → problem thread ์ฐพ๊ธฐ
โ ์ด๋ค ํจ์์ธ์ง 100% ํ์ธ ๊ฐ๋ฅ
์ํ๋ฉด ์ง๊ธ ์ฌ์ฉ ์ค์ธ Java ์๋ฒ์์
๋ฌธ์ ๊ฐ ๋๋ thread๋ฅผ ์ค์๊ฐ์ผ๋ก ์ฐพ๋ ์ ์คํฌ๋ฆฝํธ๋ ๋ง๋ค์ด์ค๊ฒ!
๋์ ๋ง:
ChatGPT์ ๋ง:
์ ์ ์์ต๋๋ค.
๋จ์ํ “thread ID ์ซ์๋ง ๋ณด์ธ๋ค → ์ฝ๋ ์์น๋ ๋ชจ๋ฅธ๋ค”๊ฐ ์๋๋ผ,
thread ID(TID) → jstack → Java ํจ์๋ช
+ ํ์ผ๋ช
+ ๋ผ์ธ๋ฒํธ๊น์ง ์ ํํ ์ฐพ์ ์ ์์ต๋๋ค.
์ฆ,
โ thread ID๋ง ์๋ฉด “์ด๋ค ์ฝ๋(์ด๋ค ํจ์)๊ฐ ๋ฌธ์ ์ธ์ง 100% ์ถ์ ๊ฐ๋ฅํฉ๋๋ค.”
์๋๋ฅผ ๋ณด๋ฉด ์ ๊ฐ๋ฅํ์ง ์ดํด๋ฉ๋๋ค.
๐ฅ ํต์ฌ ๊ฐ๋ :
๋ฆฌ๋ ์ค์์ ๋ณด์ด๋ thread ID(TID)๋ JVM ๋ด๋ถ ์ค๋ ๋์ nid(native thread id)์ 1:1๋ก ๋งคํ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด top์์:
๋ผ๊ณ CPU๋ฅผ ๋ง์ด ๋จน๋ ์ค๋ ๋๊ฐ ๋ณด์ด๋ฉด,
- ์ด๊ฑธ HEX๋ก ๋ฐ๊พธ๊ณ
- jstack์์ ํด๋น TID๋ฅผ ๊ฒ์ํ๋ฉด
- ๊ทธ ์ค๋ ๋๊ฐ ์ด๋ค Java ์ฝ๋(๋ฉ์๋) ๋ฅผ ์คํ ์ค์ธ์ง ์ ํํ ์ ์ ์์ต๋๋ค.
์ค์ ๋ก ์ด๋ ๊ฒ ๋์ต๋๋ค:
๐ ์ค์ ์์ (์ด๊ฒ ์ค์ ๋ก ๋์ค๋ ํ๋ฉด)
Step1 — CPU ๋ง์ด ๋จน๋ thread ์ฐพ๊ธฐ
์:
Step2 — 10์ง์๋ฅผ 16์ง์(hex)๋ก ๋ณํ
์ถ๋ ฅ:
Step3 — jstack ๋คํ ์์ฑ
Step4 — ๋ฌธ์ ์ค๋ ๋ ๊ฒ์
๐ฅ ์ค์ ๋ก ๋ณด์ด๋ ๊ฒฐ๊ณผ
์ฆ, thread ID ํ๋๋ง์ผ๋ก
- ์ด๋ค ํด๋์ค์ธ์ง
- ์ด๋ค ๋ฉ์๋์ธ์ง
- ๋ช ๋ฒ์งธ ์ค(line number)์ธ์ง
→ ์ ํํ ๋์จ๋ค.
์ฌ๊ธฐ์๋:
- calculateFee() ํจ์๊ฐ CPU๋ฅผ ํญ์ฃผ์ํค๊ณ ์์
- ํ์ผ: PaymentService.java
- ๋ผ์ธ: 183
์ด ์์ค๊น์ง ๋ฐ๋ก ์ ์ ์์ต๋๋ค.
๐ก ์ ๋ฆฌํ๋ฉด
โ thread ID ์์ฒด๋ก๋ ์ฝ๋ ์ด๋ฆ์ด ์ ๋ณด์ด์ง๋ง
โ thread ID → jstack ๊ฒ์์ ํ๋ฉด
๐ ์ค๋ ๋๊ฐ ์คํ ์ค์ธ ๋ฉ์๋
๐ ๋ฉ์๋๊ฐ ์๋ ํด๋์ค
๐ Java ํ์ผ ์ด๋ฆ
๐ ๋ผ์ธ ๋ฒํธ
๐ Lock held ์ฌ๋ถ
๐ JVM ์ํ(runnable / waiting / blocked)
๊น์ง ์ ๋ถ ์ ์ ์์ต๋๋ค.
๐ฏ ๊ฒฐ๋ก
thread ID๋ง ์๋ฉด ์ด๋ค ์ฝ๋๊ฐ ๋ฌธ์ ์ธ์ง 100% ์ฐพ์๋ผ ์ ์์ต๋๋ค.
๋จ์ํ ์ถ๋ก ์ด ์๋๋ผ, ์ค์ Java stack trace์ ๋ฉ์๋/๋ผ์ธ๋ฒํธ๊ฐ ์ ํํ ์ฐํ๋๋ค.



