JiwonDev

JVM(์ž๋ฐ”๊ฐ€์ƒ๋จธ์‹ )๊ณผ JRE, JDK

by JiwonDev

์šด์˜์ฒด์ œ์™€ ํ•˜๋“œ์›จ์–ด์— ๋…๋ฆฝ์ ์ธ ์–ธ์–ด, 1995๋…„ ๋‹น์‹œ ์ด ๊ฐœ๋…์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํ˜์‹ ์ด์—ˆ๋‹ค.

์ฐธ๊ณ ๋กœ ์ž๋ฐ”๋Š” ์ฌ ๋งˆ์ดํฌ๋กœ์‹œ์Šคํ…œ์Šค๊ฐ€ ๊ฐœ๋ฐœํ–ˆ์ง€๋งŒ JVM ๋ช…์„ธ(Specification)๋งŒ ๋”ฐ๋ฅธ๋‹ค๋ฉด ๋ˆ„๊ตฌ๋‚˜ ๊ฐœ๋ฐœํ•ด์„œ JVM ๋ฒค๋”๋ฅผ ์ œ๊ณตํ•  ์ˆ˜๋„์žˆ๋‹ค. ํ˜„์žฌ ์ž๋ฐ”๋Š” ์˜ค๋ผํด์ด ์ธ์ˆ˜ํ–ˆ์œผ๋ฏ€๋กœ ๋ณดํ†ต์˜ ๊ฒฝ์šฐ ์˜ค๋ผํด์—์„œ ๊ฐœ๋ฐœํ•œ ํ•ซ์ŠคํŒŸ JVM์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

Write Once, Run Anywhere (์ž๋ฐ” ์Šฌ๋กœ๊ฑด)


# 1. ์ž๋ฐ” ๊ฐ€์ƒ๋จธ์‹  (Java Virtual Machine, JVM)

๊ฐ€์ƒ๋จธ์‹ ์ด๋ผ๋Š” ๊ฐœ๋…์€ ์—ฌ๋Ÿฌ๊ฐ€์ง€๋กœ ์ •์˜ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์˜๋ฏธ๋กœ๋งŒ ์–ด๋– ํ•œ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋Š” ๋ฌผ๋ฆฌ์  ๋จธ์‹ ์„ ์†Œํ”„ํŠธ์›จ์–ด๋กœ ๊ตฌํ˜„ํ•œ ๊ฒƒ์„ ๋งํ•œ๋‹ค. ์œˆ๋„์šฐ์—์„œ '๋ฆฌ๋ˆ…์Šค ๊ฐ€์ƒ๋จธ์‹  ํ”„๋กœ๊ทธ๋žจ'์„ ํ†ตํ•ด ๋ฆฌ๋ˆ…์Šค ์šด์˜์ฒด์ œ๋ฅผ ์‹คํ–‰์‹œํ‚ค๋Š” ๊ฒƒ์„ ์ƒ์ƒํ•˜๋ฉด ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค. ์ž๋ฐ”์—์„œ๋Š” ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผ ํ•  ๋•Œ ๋ฐ”๋กœ ๊ธฐ๊ณ„์–ด๋กœ ๋ฒˆ์—ญํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ์ค‘๊ฐ„๋‹จ๊ณ„์˜ '๋ฐ”์ดํŠธ ์ฝ”๋“œ (.class ํŒŒ์ผ)'๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. ์ดํ›„ ์ž๋ฐ”์‹คํ–‰ํ™˜๊ฒฝ(JRE)์— ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์‹คํ–‰์‹œํ‚ค๋ฉด JVM(์ž๋ฐ”๊ฐ€์ƒ๋จธ์‹ ) ์œ„์—์„œ ๋ชจ๋“  ์ข…๋ฅ˜์˜ ํ•˜๋“œ์›จ์–ด์— ๋™์ž‘ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฒˆ์—ญ, ์‹คํ–‰๋œ๋‹ค.

์ข€ ๋” ๊ฐ„๋žตํ•˜๊ฒŒ ์„ค๋ช…ํ•˜์ž๋ฉด, ์ž๋ฐ” ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋Š” JRE์—์„œ ๋™์ž‘ํ•œ๋‹ค. JRE๋Š” ํฌ๊ฒŒ <์ž๋ฐ” API>์™€ <JVM> ์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์œผ๋ฉฐ JVM์˜ ์—ญํ• ์€ ์ž๋ฐ” ์ฝ”๋“œ๋ฅผ Class Loader๋ฅผ ํ†ตํ•ด ์ฝ์–ด๋“ค์—ฌ ์ž๋ฐ” API์™€ ํ•จ๊ป˜ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

์ฐธ๊ณ ๋กœ JDK๋Š” (JRE + ๊ฐœ๋ฐœ, ์ปดํŒŒ์ผ๋„๊ตฌ)๋ฅผ ์˜๋ฏธํ•˜๋ฉฐ Java11 ๋ฒ„์ „ ์ดํ›„๋กœ๋Š” JRE๋ฅผ ๋”ฐ๋กœ ์ œ๊ณตํ•˜์ง€ ์•Š๊ณ  JDK๋ฅผ ์ œ๊ณตํ•œ๋‹ค.


# 2. JVM์˜ ํŠน์ง•

JVM์—์„œ ๋™์ž‘ํ•˜๋Š” ์ž๋ฐ” ๋ฐ”์ดํŠธ์ฝ”๋“œ(.class)๋Š” CPU, ์šด์˜์ฒด์ œ์— ๋…๋ฆฝ์ ์ด๊ณ  ์ปดํŒŒ์ผ ๊ฒฐ๊ณผ๋ฌผ์˜ ํฌ๊ธฐ๊ฐ€ ๊ธฐ์กด ์†Œ์Šค์ฝ”๋“œ์™€ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์•„ ๋„คํŠธ์›Œํฌ๋กœ ์ „์†กํ•˜์—ฌ ์‹คํ–‰ํ•˜๊ธฐ ์‰ฝ๋‹ค. ์ด๊ฒŒ ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ํŠน์ง• ๋•๋ถ„์ด๋‹ค.

  • ์Šคํƒ๊ธฐ๋ฐ˜์˜ ๊ฐ€์ƒ๋จธ์‹ 
    ์ปดํ“จํ„ฐ ๊ตฌ์กฐ์— ๋Œ€ํ•ด ๋ฐฐ์› ๋‹ค๋ฉด, CPU์˜ ์•„ํ‚คํ…์ณ์— ๋”ฐ๋ผ ๋ช…๋ น์–ด์™€ ๋ ˆ์ง€์Šคํ„ฐ์˜ ์ˆ˜๊ฐ€ ๋‹ค๋ฆ„์„ ์•Œ๊ณ ์žˆ์„ ๊ฒƒ์ด๋‹ค. JVM์—์„œ๋Š” ๋‹ค์–‘ํ•œ ํ”Œ๋žซํผ ์ง€์›์„ ์œ„ํ•ด ๋ ˆ์ง€์Šคํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฉ”๋ชจ๋ฆฌ '์Šคํƒ ๊ธฐ๋ฐ˜'์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

  • symbolic references (์‹ฌ๋ณผ๋ฆญ ๋ ˆํผ๋Ÿฐ์Šค)
    ๊ธฐ๋ณธ ์ž๋ฃŒํ˜•์„ ์ œ์™ธํ•œ ๋ชจ๋“ ํƒ€์ž…์€ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ๊ธฐ๋ฐ˜ ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ์•„๋‹Œ ์‹ฌ๋ณผ๋ฆญ ๋ ˆํผ๋Ÿฐ์Šค๋กœ ์ œ๊ณต๋œ๋‹ค. ์‰ฝ๊ฒŒ๋งํ•ด ์ฐธ์กฐํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š๊ณ  ํ•ด๋‹น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ด๋ฆ„(=์‹ฌ๋ณผ) ๋งŒ ๊ธฐ๋กํ•ด๋†“๋Š” ๋ฐฉ๋ฒ•. ์ด๋Š” ์ž๋ฐ” ์ฝ”๋“œ๊ฐ€ ๋ฐ”๋กœ ๊ธฐ๊ณ„์–ด๋กœ ๋ฒˆ์—ญ๋˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด JVM ๋‚ด์—์„œ ์‹คํ–‰๋˜๊ธฐ์— ๊ฐ€๋Šฅํ•˜๋‹ค.

  • ์ž๋ฃŒํ˜•์˜ ๋ช…ํ™•์„ฑ, ํ”Œ๋žซํผ ๋…๋ฆฝ์„ฑ ๋ณด์žฅ
    ์ž๋ฐ”๋Š” ์• ์ดˆ๋ถ€ํ„ฐ ์—ฌ๋Ÿฌ ์šด์˜์ฒด์ œ์— ์‚ฌ์šฉํ• ๋ ค๊ณ  ์„ค๊ณ„ํ•˜์˜€๊ธฐ์— ํ”Œ๋žซํผ์— ๋”ฐ๋ผ ์ž๋ฃŒํ˜•์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ๊ฐ€ ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค. (C์–ธ์–ด ๊ฐ™์€ ์ „ํ†ต์ ์ธ ์–ธ์–ด๋Š” ์šด์˜์ฒด์ œ์— ๋”ฐ๋ผ int ํ˜• ๊ฐ™์€ ๊ธฐ๋ณธ ์ž๋ฃŒํ˜•์˜ ํฌ๊ธฐ๊ฐ€ ๋‹ค๋ฅด๋‹ค.)

  • Network byte order (๋„คํŠธ์›Œํฌ ๋ฐ”์ดํŠธ ์˜ค๋”)
    ์ž๋ฐ” ๋ฐ”์ดํŠธ์ฝ”๋“œ(.class)๋Š” ๋„คํŠธ์›Œํฌ ๋ฐ”์ดํŠธ ์˜ค๋”๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์ €์žฅ๋ฐฉ์‹(๋น…์—”๋””์•ˆ, ๋ฆฌํ‹€์—”๋””์•ˆ)์— ํ”Œ๋žซํผ ๋…๋ฆฝ์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๋„คํŠธ์›Œํฌ ์ „์†ก์‹œ์— ํ‘œ์ค€์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ”์ดํŠธ ์˜ค๋”(= ๋น…์—”๋””์•ˆ)์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๋ง. 

๊ทธ๋ฆฌ๊ณ  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•˜์ง€์•Š๋Š” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ ๊ฐœ๋…์ด ์ž๋ฐ”์—์„œ ์ฒ˜์Œ ๋“ฑ์žฅํ•˜์˜€๋‹ค.


# Garbage Colletcion

์ž๋ฐ” ์ด์ „์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ง์ ‘ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ƒ์„ฑ๊ณผ ํšŒ์ˆ˜๋ฅผ ๊ด€๋ฆฌํ•˜์˜€๋‹ค. ์ž๋ฐ”์—์„œ๋Š” JVM์— ๋‚ด์žฅ๋œ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ์˜ ํ• ๋‹น๊ณผ ํšŒ์ˆ˜๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๋ฉด ์ฐธ์กฐ ๋˜์ง€ ์•Š๋Š” ๊ฐ์ฒด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐพ์•„ ๋Ÿฐํƒ€์ž„์—์„œ ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํšŒ์ˆ˜ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

 

# JIT (Just-In-Time)

์ž๋ฐ”์˜ ๋ฐ”์ดํŠธ์ฝ”๋“œ(.class)๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ธํ„ฐํ”„๋ฆฌํ„ฐ์ฒ˜๋Ÿผ ๋™์ž‘ํ•œ๋‹ค. ์ฆ‰ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ํ•œ์ค„์”ฉ ์‹คํ–‰ํ•˜์—ฌ ํ•ด์„ํ•œ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ์™€ ๋‹ค๋ฅด๊ฒŒ ์ธํ„ฐํ”„๋ฆฌํ„ฐ์˜ ๊ฒฝ์šฐ ์ „์ฒด์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ์„œ ์ตœ์ ํ™”๊ฐ€ ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ๋™์ผํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์—ฌ๋Ÿฌ๋ฒˆ ํ•ด์„ํ•˜๋Š” ๋น„ํšจ์œจ์ ์ธ ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•œ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ์œ„ํ•ด ์ž๋ฐ”์—์„œ๋Š” JIT(Just-In-Time) ๋ฐฉ์‹์˜ ์ปดํŒŒ์ผ์„ ์‚ฌ์šฉํ•œ๋‹ค. ์ดˆ๊ธฐ ์‹คํ–‰ ์‹œ์ ์— ์ž์ฃผ ์‚ฌ์šฉ๋ ๋งŒํ•œ ์ฝ”๋“œ๋“ค์„ ๋ฏธ๋ฆฌ ๊ธฐ๊ณ„์–ด๋กœ ํ•ด์„ํ•˜์—ฌ ์ €์žฅ(=์บ์‹ฑ)ํ•ด๋†จ๋‹ค๊ฐ€ ์žฌ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

 


# JVM์˜ ๋™์ž‘

  • Class Loader
    ์ž๋ฐ” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ฝ”๋“œ(.java)๋ฅผ ๋ฐ”์ดํŠธ์ฝ”๋“œ(.class)๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด ์ด๋ฅผ JRE์— ๋กœ๋”ฉํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค. ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋Š” JVM ์•ˆ์—์žˆ๋Š” Class Loader์— ์˜ํ•ด ๋Ÿฐํƒ€์ž„ ์‹œ์ ์— ๋กœ๋”ฉ๋˜๋Š”๋ฐ, ์ด ์‹œ์ ์—์„œ Lazy Loading์„ ๊ตฌํ˜„ํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

  • ์‹คํ–‰ ์—”์ง„ (Execution Engine)
    Class Loader๋กœ ๋ถˆ๋Ÿฌ์˜จ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋“ค์„ ์‹คํ–‰ํ•œ๋‹ค. 1๋ฐ”์ดํŠธ์˜ OpCode์™€ ํ”ผ์—ฐ์‚ฐ์ž๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. ์ด ์‹œ์ ์— ์œ„์— ์„ค๋ช…ํ•œ JIT ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค.

  • Garbage Collector
    Heap ์˜์—ญ์—์„œ ์ฐธ์กฐ๋˜์ง€ ์•Š๋Š” ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค. ๋ฌผ๋ก  ์‹ค์ œ ๊ตฌํ˜„์€ ํ›จ์”ฌ ๋ณต์žกํ•œ๋ฐ ๊ถ๊ธˆํ•˜๋ฉด ๊ตฌ๊ธ€์— ๊ฒ€์ƒ‰ํ•ด๋ณด์ž.

  • Runtime Data Areas
    OS(์šด์˜์ฒด์ œ)๋กœ ๋ถ€ํ„ฐ JRE๊ฐ€ ํ• ๋‹น๋ฐ›์€ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์ด๋‹ค. ์ž๋ฐ” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๋Š” ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š”๋‹ค.

 

# ๋ฐ”์ดํŠธ์ฝ”๋“œ๋Š” ๋ชฐ๋ผ๋„ ๋˜๋Š”๊ฑฐ ์•„๋‹Œ๊ฐ€์š”?

D2 naver์˜ ๋ธ”๋กœ๊ทธ ๋‚ด์šฉ์„ ์ฐธ์กฐํ•˜์˜€๋‹ค.

 

1. ํ˜„์ƒ

๊ธฐ์กด์— ์ž˜ ์ž‘๋™ํ•˜๋˜ ์ž๋ฐ” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ฐ‘์ž๊ธฐ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜(NoSuchMethodError)๋ฅผ ๋‚ธ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

Exception in thread "main" java.lang.NoSuchMethodError: com.user.UserAdmin.addUser(Ljava/lang/String;)V  
at com.service.UserService.add(UserService.java:14)  
at com.service.UserService.main(UserService.java:19)  

 

๋‚ด๊ฐ€ ๊ฐœ๋ฐœํ•œ ์ž๋ฐ” ์ฝ”๋“œ๋Š” ๊ธฐ์กด์˜ ์ž˜ ์ž‘๋™๋˜๋˜ ์ฝ”๋“œ์—์„œ ๋”ฐ๋กœ ๋ณ€๊ฒฝํ•œ๊ฒŒ ์—†์œผ๋ฉฐ, ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ์ด๋‹ค.

// UserService.java
…
public void add(String userName) {  
admin.addUser(userName);  
}

๋‹ค๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—…๋ฐ์ดํŠธ ๋˜์—ˆ๋Š”๋ฐ, ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

์ฝ”๋“œ์ƒ์—๋Š” ๋ณ„ ๋ฌธ์ œ ์—†์–ด๋ณด์ด๋Š”๋ฐ, ์™œ ์œ„์—์„œ๋Š” NoSuchMethodError๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ผ๊นŒ?

// UserAdmin.java - ์—…๋ฐ์ดํŠธ๋œ ์†Œ์Šค์ฝ”๋“œ
…
public User addUser(String userName) {  
User user = new User(userName);  
User prevUser = userMap.put(userName, user);  
return prevUser;  // ๋ฐ˜ํ™˜ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค.
// ๋‹จ์ˆœํžˆ ๋ณด๊ธฐ์—๋Š” com.user.UserAdmin.Admin.addUser() ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ์— ๋ฌธ์ œ๊ฐ€ ์—†์–ด๋ณด์ธ๋‹ค.
}

// UserAdmin.java - ์›๋ž˜ ์†Œ์Šค์ฝ”๋“œ
…
public void addUser(String userName) {  
User user = new User(userName);  
userMap.put(userName, user);  
}

2. ์›์ธ

์›์ธ์€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๋ฅผ '์ƒˆ๋กœ์šด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ' ๋ฒ„์ „์œผ๋กœ ๋‹ค์‹œ ์ปดํŒŒ์ผํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ž๋ฐ” ์ฝ”๋“œ์ƒ์œผ๋กœ ๋ณด๊ธฐ์—๋Š” ๋ฐ˜ํ™˜๊ฐ’๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ ๊ฐ™์ง€๋งŒ, ์‹ค์ œ ์ปดํŒŒ์ผ ๋œ ๋ฐ”์ดํŠธ์ฝ”๋“œ(.class) ํŒŒ์ผ์€ ๋ฐ˜ํ™˜๊ฐ’๊นŒ์ง€ ์ง€์ •๋œ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

Exception in thread "main" java.lang.NoSuchMethodError: com.user.UserAdmin.addUser(Ljava/lang/String;)V  

์ด ์˜ค๋ฅ˜์˜ ์˜๋ฏธ๋Š” com.user.UserAdmin.addUser()๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. ๋ฉ”์„œ๋“œ์— ์ ํ˜€์žˆ๋Š” L, V๋Š” ์˜คํƒ€๊ฐ€ ์•„๋‹ˆ๋ผ ์ž๋ฐ” ๋ฐ”์ดํŠธ์ฝ”๋“œ ํ‘œํ˜„์—์„œ (Ljava/lang/String) ์—์„œ L์€ ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค๋ฅผ, (...)V๋Š” ๋ฐ˜ํ™˜๊ฐ’์ด ์—†๋Š” ๋ฉ”์„œ๋“œ์ž„์„ ์˜๋ฏธํ•œ๋‹ค.

 

์ฆ‰, ํ•ด๋‹น ์ž๋ฐ”์ฝ”๋“œ๋Š” ์ด์ „์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ฐธ์กฐํ•˜๋ฏ€๋กœ ์—…๋ฐ์ดํŠธ ๋œ ์‹ ๊ทœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๊ฐ์ฒด 1๊ฐœ๋ฅผ ์ž…๋ ฅ๊ฐ’์œผ๋กœ ๋ฐ›๊ณ  ๋ฐ˜ํ™˜๊ฐ’์ด ์—†๋Š” addUser()๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค. 

 

3. ์„ค๋ช…

๋ฌผ๋ก  ์˜ค๋ฅ˜ ์ž์ฒด๋Š” ๋ฉ”์„œ๋“œ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๋งˆ์Œ๋Œ€๋กœ ๋ณ€๊ฒฝํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ œ๊ณต์ž์˜ ์ž˜๋ชป์ด ๋งค์šฐ ํฌ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ ๊ฐœ๋ฐœํ•จ์— ์žˆ์–ด ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์„ ๋งˆ์ง€ํ•œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋Œ€์ฒ˜ ํ•  ์ˆ˜ ์žˆ์„๊นŒ? ํ•˜๋ฃจ์ข…์ผ ์ฝ”๋“œ๋ฅผ ๋””๋ฒ„๊น… ํ•œ๋‹ค ํ•œ๋“ค ๊ณผ์—ฐ ๋ฌธ์ œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์„๊นŒ?

 

์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ ํฐ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ ๋ฐ”์ดํŠธ ์ฝ”๋“œ์— ๋Œ€ํ•œ ์ดํ•ด์ด๋‹ค. ๋ฌผ๋ก  ํด๋ž˜์Šค(.class) ํŒŒ์ผ ์ž์ฒด๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ์ด๋ผ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๊ธฐ์— JVM ์— ํ•จ๊ป˜ ์ œ๊ณต๋˜๋Š” ์—ญ์–ด์…ˆ๋ธ”๋Ÿฌ(disaasembler)๋ฅผ ์ด์šฉํ•ด์„œ ๋ถ„์„ํ•œ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—…๋ฐ์ดํŠธ ํ•˜๊ธฐ ์ „ add() ์ฝ”๋“œ๋ฅผ javap -c ๋ช…๋ น์–ด๋กœ ์—ญ์–ด์…ˆ๋ธ”ํ•œ ๊ฒฐ๊ณผ๋ฌผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

/*
 // ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—…๋ฐ์ดํŠธ ์ „ add ์ฝ”๋“œ
  public void add(String userName) {  
 	 admin.addUser(userName);  
  }
*/

public void add(java.lang.String);  
Code:  
0: aload_0  
1: getfield #15; //Field admin:Lcom/nhn/user/UserAdmin;  
4: aload_1  
5: invokevirtual #23; //Method com/nhn/user/UserAdmin.addUser:(Ljava/lang/String;)V  
8: return  

์ด ๋ฐ”์ดํŠธ์ฝ”๋“œ์—์„œ addUser()๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ถ€๋ถ„์€ [ 5: invokevirtual #23 ]์ด๋‹ค. ์ด๋Š” 23๋ฒˆ ์ธ๋ฑ์Šค์—์„œ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ผ๋Š” ์˜๋ฏธ์ด๋ฉฐ ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ javap ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ฃผ์„์„ ๋‹ฌ์•„์ฃผ์—ˆ๋‹ค.

invokevirtual์€ ์ด๋ฆ„์—์„œ ์œ ์ถ” ํ•  ์ˆ˜ ์žˆ๋“ฏ์ด ์ž๋ฐ” ๋ฐ”์ดํŠธ์ฝ”๋“œ์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ธฐ๋ณธ์ ์ธ ๋ช…๋ น์–ด์˜ OpCode ์ด๋‹ค.

  • invokeinterface: ์ธํ„ฐํŽ˜์ด์Šค ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
  • invokespecial: ์ƒ์„ฑ์ž, private ๋ฉ”์„œ๋“œ, ์Šˆํผ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
  • invokestatic: static ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
  • invokevirtual: ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
  • ๊ทธ ์™ธ ํ”ผ์—ฐ์‚ฐ์ž (Operand)

์ด๋ฅผ ์—…๋ฐ์ดํŠธ๋œ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์—ญ์–ด์…ˆ๋ธ”ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

/*
 // ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—…๋ฐ์ดํŠธ ํ›„ add ์ฝ”๋“œ (๋™์ผ)
  public void add(String userName) {  
 	 admin.addUser(userName);  
  }
*/
public void add(java.lang.String);  
Code:  
0: aload_0  
1: getfield #15; //Field admin:Lcom/nhn/user/UserAdmin;  
4: aload_1  
5: invokevirtual #23; //Method com/nhn/user/UserAdmin.addUser:(Ljava/lang/String;)Lcom/nhn/user/User;  
8: pop  
9: return  

์ด๋ ‡๊ฒŒ ๋ฐ”์ดํŠธ์ฝ”๋“œ ๋ถ„์„์„ ํ†ตํ•ด ์–ด๋–ค ๋ถ€๋ถ„์ด ๋‹ฌ๋ผ์ ธ์„œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋Š”์ง€ ์‰ฝ๊ฒŒ ์œ ์ถ” ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋ฌผ๋ก  '๊ทธ๋ƒฅ ๊ตฌ๊ธ€์— ์˜ค๋ฅ˜๋ช… ๊ทธ๋Œ€๋กœ ๊ฒ€์ƒ‰ํ•˜๋‹ˆ๊นŒ ํ•ด๊ฒฐ๋ฐฉ๋ฒ•์ด ๋‚˜์˜ค๋˜๋ฐ์š”?' ํ•˜๊ณ  ๋„˜์–ด๊ฐ€๋„ ์ƒ๊ด€์€ ์—†์œผ๋‚˜ ์ด๋Ÿฐ ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค๋Š”๊ฑธ ์ธ์ง€์ •๋„๋Š” ํ•˜๊ณ  ์žˆ์œผ๋ฉด ์ถ”ํ›„์— ๋ฐ˜๋“œ์‹œ ๋„์›€์ด ๋  ๊ฒƒ์ด๋‹ค.

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ