Skip to content

Latest commit

Β 

History

History
361 lines (226 loc) Β· 17.5 KB

java_execution.md

File metadata and controls

361 lines (226 loc) Β· 17.5 KB

Java μ½”λ“œκ°€ μ‹€ν–‰λ˜κΈ° κΉŒμ§€μ˜ μ—¬μ •

ν•΄λ‹Ή 글은 λ’€νƒœμ§€μ‘΄λ‹˜μ˜ Back to the Essence - Java μ»΄νŒŒμΌμ—μ„œ μ‹€ν–‰κΉŒμ§€ 1편과 2νŽΈμ„ 보고 μ •λ¦¬ν•œ 글이닀.
λŸ°νƒ€μž„μ‹œμ— μ‹€ν–‰ 예제의 경우 λ’€νƒœμ§€μ‘΄λ‹˜μ΄ ꡉμž₯히 친절히 μ„€λͺ…을 ν•΄μ£Όμ…¨κΈ° λ•Œλ¬Έμ— 그것을 λ³΄λŠ” 것을 μΆ”μ²œν•œλ‹€.


전톡적인 컴파일

전톡적인 컴파일의 경우 기계가 μ΄ν•΄ν•˜λŠ” κΈ°κ³„μ–΄λ‘œ λ³€ν™˜ν•˜λŠ” 것을 λ§ν•œλ‹€.

λŒ€ν‘œμ μœΌλ‘œ C μ–Έμ–΄μ˜ 경우 λ‹€μŒκ³Ό 같은 컴파일 과정을 거치게 λœλ‹€.

[Cμ–Έμ–΄] β†’ μ „μ²˜λ¦¬ β†’ 컴파일 β†’ μ–΄μ…ˆλΈ”λ¦¬ β†’ 링크 β†’ [기계어]

μš°λ¦¬κ°€ ν”„λ‘œκ·Έλž˜λ°ν•œ C μ–Έμ–΄λŠ” 주석 제거, include 파일 인라인화 λ“±μ˜ μ „μ²˜λ¦¬ 과정을 거치고, 컴파일 단계λ₯Ό 거쳐 μ–΄μ…ˆλΈ”λ¦¬μ–΄λ‘œ λ³€κ²½ν•œλ‹€.
이후 μ–΄μ…ˆλΈ”λŸ¬κ°€ 이λ₯Ό κΈ°κ³„μ–΄λ‘œ λ³€κ²½ν•˜κ³ , μ‚¬μš©ν•œ 곡유 라이브러리 등을 합쳐(링크) μ΅œμ’… μ‹€ν–‰ νŒŒμΌμ„ μƒμ„±ν•œλ‹€.


컴파일 in Java

μ΄λŸ¬ν•œ 전톡적인 μ»΄νŒŒμΌλŸ¬λŠ” 기계가 이해할 수 μžˆλŠ” κΈ°κ³„μ–΄λ‘œ λ³€ν™˜ν•œλ‹€λŠ” λͺ©μ μ„ 가진닀.

ν•˜μ§€λ§Œ, μžλ°”μ—μ„œμ˜ μ»΄νŒŒμΌμ€ μ΄μ™€λŠ” 쑰금 λ‹€λ₯΄λ‹€.
Javaλ₯Ό ν•œλ²ˆμ΄λΌλ„ μ‚¬μš©ν•΄λ³΄μ•˜μœΌλ©΄ Javaκ°€ C/C++ μ–Έμ–΄μ™€λŠ” λ‹€λ₯΄κ²Œ JVM(Java Virtual Machine)μ΄λΌλŠ” 가상 λ¨Έμ‹  μƒμ—μ„œ μ‹€ν–‰λ˜λŠ” 것을 μ•Œ 수 μžˆλ‹€.

μ΄λŸ¬ν•œ JVMμ—μ„œλŠ” κΈ°κ³„μ–΄λ‘œ ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜λŠ” 것이 μ•„λ‹Œ λ°”μ΄νŠΈμ½”λ“œλΌλŠ” μƒˆλ‘œμš΄ 쀑간 단계 μ–Έμ–΄μ—μ„œ λ°”λ‘œ ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜λ©°, 링크 과정은 JVM에 μ˜ν•΄ λ™μ μœΌλ‘œ μˆ˜ν–‰λœλ‹€.
κ·ΈλŸ¬λ―€λ‘œ Javaμ—μ„œ μ»΄νŒŒμΌμ€ Java μ–Έμ–΄λ‘œ μž‘μ„±λœ μ½”λ“œλ₯Ό JVM이 μ•Œμ•„ 듀을 수 μžˆλŠ” λ°”μ΄νŠΈμ½”λ“œλ‘œ λ³€ν™˜ν•˜λŠ” 것에 λͺ©μ μ„ 두고 μžˆλ‹€.

κ·Έλ ‡λ‹€κ³  κΈ°κ³„μ–΄λ‘œ 변경을 μ•ˆν•˜λŠ” 것은 μ•„λ‹ˆλ‹€.
JVMμ—μ„œλŠ” μ‹€ν–‰ 퍼포먼슀λ₯Ό μœ„ν•΄ JIT(Just-In-Time) 컴파일러λ₯Ό μ‚¬μš©ν•˜μ—¬ 자주 μ‚¬μš©λ˜κ±°λ‚˜ μ’€ 더 효율적으둜 지 수 μžˆλŠ” μ½”λ“œλ₯Ό κΈ°κ³„μ–΄λ‘œ λ³€ν™˜ν•˜μ—¬ μ‚¬μš©ν•˜κΈ°λ„ ν•œλ‹€.


λ°”μ΄νŠΈμ½”λ“œ 생성 κ³Όμ •

μ–΄νœ˜ 뢄석(Lexical Analysis)

μ–΄νœ˜ 뢄석기(Lexer/Tokenizer)κ°€ μ†ŒμŠ€ μ½”λ“œλ₯Ό 문자 λ‹¨μœ„λ‘œ 읽어 μ–΄νœ˜μ†Œ(Lexeme)λ₯Ό 식별 및 이λ₯Ό μ„€λͺ…ν•˜λŠ” 토큰 μŠ€νŠΈλ¦Όμ„ μƒμ„±ν•œλ‹€.
μ–΄νœ˜μ†ŒλŠ” 식별이 κ°€λŠ₯ν•œ λ¬Έμžμ—΄λ‘œ λ‹€μŒκ³Ό κ°™λ‹€.

  • ν‚€μ›Œλ“œ(Keyword)

    public, class, main λ“±

  • λ¦¬ν„°λŸ΄(Literals)

    "μ•ˆλ…•ν•˜μ„Έμš”!", 1L , 2.3f λ“±

  • μ‹λ³„μž(Identifiers)

    λ³€μˆ˜ 이름, μƒμˆ˜ 이름, ν•¨μˆ˜ 이름 λ“±

  • μ—°μ‚°μž(Operators)

    +, - λ“±

  • ꡬ뢄 문자(Punctuation characters)

    ,, [], {} λ“±

μ΄λ ‡κ²Œ μƒμ„±λœ μ‹λ³„μž 토큰은 심볼 ν…Œμ΄λΈ”μ— μ €μž₯되고 λ‹€μŒ λ‹¨κ³„μ—μ„œ μ‚¬μš©λœλ‹€.

ꡬ문 뢄석(Syntax Analysis)

ꡬ문 뢄석기(Parser)κ°€ 이전 λ‹¨κ³„μ—μ„œ λ‚˜μ˜¨ 토큰 슀트림이 문법에 λ§žλŠ”μ§€ κ²€μ‚¬ν•˜κ³  이가 λ§žλ‹€λ©΄ Parse Tree(Abstract Syntax Tree라고도 뢈림)λ₯Ό μƒμ„±ν•˜κ³ , λ§žμ§€ μ•Šλ‹€λ©΄ 컴파일 μ—λŸ¬λ₯Ό λ‚Έλ‹€.

의미 뢄석(Symantic Analysis)

이 λ‹¨κ³„μ—μ„œλŠ” νƒ€μž… 검사와 μžλ™ νƒ€μž… λ³€ν™˜λ“±μ΄ μˆ˜ν–‰λ˜λ©°, Parse Tree에 νƒ€μž… 정보 등이 μΆ”κ°€λœλ‹€.

int jong = "nan";

λ‹€μŒκ³Ό 같은 μ½”λ“œλŠ” ꡬ문 뢄석 λ‹¨κ³„κΉŒμ§€λŠ” μ—λŸ¬μ—†μ΄ ν†΅κ³Όν•˜λ‚˜, 의미 뢄석 단계λ₯Ό κ±°μΉ˜λ©΄μ„œ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

쀑간 μ½”λ“œ 생성

μ—¬λŸ¬ 단계λ₯Ό 거쳐 μƒμ„±λœ Parse Treeλ₯Ό 기반으둜 κΈ°κ³„μ–΄λ‘œ λ³€ν™˜ν•˜κΈ° 쒋은 쀑간 μ½”λ“œλ‘œ μƒμ„±ν•œλ‹€.

μ—¬κΈ°μ„œ μ™œ 쀑간 μ½”λ“œκ°€ ν•„μš”ν• κΉŒ? 라고 μ˜λ¬Έμ„ κ°€μ§ˆ 수 μžˆλ‹€.
μ΄λŠ” JVM을 μ‚¬μš©ν•˜λŠ” 이유인 "쒅속성"에 μžˆλ‹€.

λ§Œμ•½ μ–΄λ– ν•œ νšŒμ‚¬κ°€ 있고 κ·Έ νšŒμ‚¬λŠ” 기쑴에 μ–΄λ– ν•œ μ–Έμ–΄λ‘œ 슀마트폰, ν…ŒμŠ€ν¬νƒ‘ 등에 λŒ€μ‘λ˜λŠ” ν”„λ‘œκ·Έλž¨μ„ λ§Œλ“€μ—ˆλ‹€κ³  ν•˜μž.
κ·Έ μ–Έμ–΄κ°€ ꡉμž₯히 ꡬ식이고 μƒˆλ‘œμš΄ κ°œλ°œμžκ°€ μœ μž…μ΄ μ—†λŠ” μ–Έμ–΄μ—¬μ„œ λ‹€λ₯Έ μ–Έμ–΄λ‘œ λŒ€μ‘μ„ ν•΄μ•Όλ˜λŠ” 상황이 μΌμ–΄λ‚˜λ©΄, 각각의 μ œν’ˆλ§ˆλ‹€ ν”„λ‘œκ·Έλž¨μ„ λ§Œλ“€μ–΄μ•Ό ν•œλ‹€.

μœ„ 그림을 보면 세가지 μ–Έμ–΄λ‘œ μ„Έκ°œμ˜ λŒ€μ‘λ˜λŠ” ν”„λ‘œκ·Έλž¨μ„ λ§Œλ“€μ—ˆμ„ μ‹œμ— 총 9개의 ν”„λ‘œκ·Έλž¨μ„ λ§Œλ“€μ–΄μ•Ό λ˜λŠ” 것이닀.

ν•˜μ§€λ§Œ, 쀑간 μ–Έμ–΄λ‘œ λ³€ν™˜ν•˜κ³  이λ₯Ό λŒμ•„κ°ˆ 수 μžˆλŠ” 가상 머신을 λ§Œλ“ λ‹€λ©΄?

각자의 ν•˜λ‚˜μ”©μ˜ ν”„λ‘œκ·Έλž¨λ§Œ λ§Œλ“€λ©΄ 되기 λ•Œλ¬Έμ— νš¨μœ¨μ„±μ΄ 높아진닀.

이 λ‹¨κ³„μ—μ„œλŠ” 쀑간 μ½”λ“œλ₯Ό μƒμ„±ν•˜λŠ” κ²ƒλΏλ§Œ μ•„λ‹ˆλΌ 여지것 λ§Œλ“€μ–΄μ™”λ˜ μ •λ³΄λ“€λ‘œ 클래슀/μΈν„°νŽ˜μ΄μŠ€μ˜ μƒμˆ˜ ν’€(Constant Pool)을 λ§Œλ“œλŠ” 데 μ‚¬μš©λœλ‹€.
μƒμˆ˜ ν’€μ˜ 경우 μ‹€μ œλ‘œ μ½”λ“œκ°€ λŒμ•„κ°€λ©΄μ„œ 클래슀/μΈν„°νŽ˜μ΄μŠ€κ°€ 생성될 λ•Œ μ‚¬μš©ν•˜λŠ” Run-Time Constant Pool을 κ΅¬μ„±ν•˜λŠ”λ° μ‚¬μš©λœλ‹€.

쀑간 μ½”λ“œ μ΅œμ ν™”(Code Optimization)

쀑간 μ½”λ“œλ₯Ό 더 효율적인 κΈ°κ³„μ–΄λ‘œ λ³€ν™˜ν•˜κΈ° μœ„ν•΄ μ΅œμ ν™” 과정을 거치게 λœλ‹€.
μ΅œμ ν™” 방법은 λ‹€μŒκ³Ό 같이 맀우 λ‹€μ–‘ν•˜λ‹€.

  • Peephole μ΅œμ ν™”

    쀑볡 λͺ…λ Ήμ–΄ 및 도달 λΆˆκ°€λŠ₯ν•œ μ½”λ“œ 제거, μ œμ–΄ 흐름 μ΅œμ ν™”, λΉ„μš©μ΄ 적은 μ—°μ‚°μžλ‘œ λ³€ν™˜ λ“±

  • 지역 μ΅œμ ν™”

    지역 곡톡 λΆ€λΆ„ 제거, 볡사 μ „νŒŒ, μƒμˆ˜ 폴딩 λ“±

  • 루프 μ΅œμ ν™”

    μ½”λ“œ 이동, κ·€λ‚© λ³€μˆ˜ μ΅œμ ν™”, 루프 μœ΅ν•©/κ΅ν™˜/μ „κ°œ λ“±

  • μ „μ—­ μ΅œμ ν™”

    μ „μ—­ 곡톡 뢀뢄식 제거, μƒμˆ˜ 폴딩 λ“±


JVM의 μ™ΈλΆ€ ν™˜κ²½ 및 ꡬ동 μ€€λΉ„

μžλ°” μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‹€ν–‰ν•˜λŠ” λͺ…λ Ήμ–΄λŠ” java이닀.
이 λͺ…λ Ήμ–΄λŠ” JRE(Java Runtime Environment)λ₯Ό μ‹œμž‘ν•˜κ³ , 인자둜 μ§€μ •λœ 클래슀λ₯Ό λ‘œλ”© 후에 main() λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€.

μžλ°”λ‘œ ν”„λ‘œκ·Έλž˜λ°μ„ ν•˜λ‹€λ³΄λ©΄ JDK, JRE λ“±λ“± 많이 듀어봀을 것이닀.
μ΄λ“€μ˜ 상관 κ΄€κ³„λŠ” λ‹€μŒ κ·Έλ¦Όκ³Ό κ°™λ‹€.

  • JDK (Java Development Kit)

    μžλ°”λ₯Ό κ°œλ°œν•  λ•Œ μ‚¬μš©λ˜λŠ” 도ꡬ λͺ¨μŒμœΌλ‘œ 컴파일러, μ—­μ–΄μ…ˆλΈ”λŸ¬, 디버거 등을 μ œκ³΅ν•œλ‹€.

  • JRE (Java Runtime Environment)

    μžλ°”λ‘œ λ§Œλ“€μ–΄μ§„ ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜κΈ° μœ„ν•΄ 클래슀 λ‘œλ”, κΈ°λ³Έ 라이브러리 등을 μ œκ³΅ν•œλ‹€.

  • JVM (Java Virtual Machine)

    인터프리터, JIT 컴파일러, 링컀, 가비지 컬릭터 λ“± μ—¬λŸ¬ OS에 λ…λ¦½μ μœΌλ‘œ μ‹€ν–‰ 될 수 μžˆλŠ” 좔상측을 μ œκ³΅ν•œλ‹€.

κ°„λ‹¨ν•˜κ²Œ 정리λ₯Ό 해보면, JDKλ₯Ό 톡해 κ°œλ°œμžκ°€ μž‘μ„±ν•œ μ½”λ“œλ₯Ό λ°”μ΄νŠΈ μ½”λ“œλ‘œ λ³€κ²½ν•˜κ³  이λ₯Ό JREλ₯Ό μ‚¬μš©ν•˜μ—¬ μ‹€ν–‰λ˜μ–΄μ§€λ©° JVM이 κ΅¬λ™λ˜λ©΄μ„œ λ°”μ΄νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜κ²Œ λœλ‹€.


JVM의 λ©”λͺ¨λ¦¬ μ˜μ—­

λ°”λ‘œ μ „ μž₯μ—μ„œ JVM μ™ΈλΆ€ ν™˜κ²½μ—μ„œλΆ€ν„° μ‹€μ œ ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰ν•˜κΈ° μ§μ „κΉŒμ§€ μ•Œμ•„λ³΄μ•˜λ‹€.
λ§Žμ€ κ°œλ°œμžκ°€ μ˜ˆμƒν•˜λ‹€μ‹œν”Ό κ°„λ‹¨ν•˜κ²Œ λΏ…ν•˜κ³  μ‹€ν–‰λ˜λŠ” 것이 μ•„λ‹ˆλ‹€.
그럼 μ„ΈλΆ€μ μœΌλ‘œ μ–΄λ–»κ²Œ μ‹€ν–‰λ˜λŠ”μ§€ μ‚΄νŽ΄λ³΄μž.

Run-Time Data Area

λͺ…λ Ήμ–΄λ₯Ό 톡해 ν”„λ‘œκ·Έλž¨μ΄ 싀행될 λ•Œ, Class Loader(클래슀 λ‘œλ”)κ°€ μ‹œμž‘ 클래슀(κ°œλ°œμžκ°€ μ •μ˜ν•œ 클래슀)λ₯Ό μƒμ„±ν•˜κ²Œ λ˜λŠ”λ° μ΄λŠ” JVM μ•ˆμ— μžˆλŠ” λ©”λͺ¨λ¦¬μ— ν•΄λ‹Ή 클래슀λ₯Ό μ μž¬ν•œλ‹€λŠ” λœ»μ΄λ‹€.
JVM μ•ˆμ— λ©”λͺ¨λ¦¬ μ˜μ—­μ΄ λ”°λ‘œ 있으며 μš°λ¦¬λŠ” 이것을 Run-Time Data Area라고 ν•œλ‹€.

이 λ©”λͺ¨λ¦¬ μ˜μ—­μ€ 크게 6개 κ΅¬μ—­μœΌλ‘œ λ‹€μŒκ³Ό 같이 λ‚˜λ‰  수 μžˆλ‹€.

  • Heap (JVM λ‹¨μœ„)
  • Method Area (JVM λ‹¨μœ„)
  • Run-Time Constant Pool (Class λ‹¨μœ„)
  • PC Register (μŠ€λ ˆλ“œ λ‹¨μœ„)
  • JVM Stack (μŠ€λ ˆλ“œ λ‹¨μœ„)
  • Native Method Stack (μŠ€λ ˆλ“œ λ‹¨μœ„)

κ°€λ‘œ μ•ˆμ— JVM, Class, μŠ€λ ˆλ“œ λ‹¨μœ„λ₯Ό 적어 λ†“μ•˜λŠ”λ° μ΄λŠ” 3개의 λ‹¨μœ„λ‘œ ν•΄λ‹Ή μ˜μ—­λ“€μ΄ μƒμ„±λ˜κ³  μ‚­μ œλ˜κΈ° λ•Œλ¬Έμ΄λ‹€.

Heap κ³Ό Method Area 은 JVM이 ꡬ동 λ˜μ–΄μ§ˆ λ•Œ 같이 생성/μ†Œλ©Έμ„ ν•˜λ©° ν•˜λ‚˜μ”© μƒμ„±λœλ‹€.

Run-TIme Constant Pool 은 ν΄λž˜μŠ€κ°€ λ‘œλ“œλ˜μ–΄ μƒμ„±μ‹œ 같이 μƒμ„±λ˜λ©° 생λͺ…μ£ΌκΈ°λ₯Ό ν•¨κ»˜ν•œλ‹€.

λ‚˜λ¨Έμ§€ PC Register, JVM Stack, Native Method Stack 은 μŠ€λ ˆλ“œμ™€ 같이 생성/μ†Œλ©Έ λœλ‹€.

이제 μ‹€ν–‰λ˜λŠ” μˆœμ„œλ³„λ‘œ μ˜μ—­λ“€μ„ μžμ„Ένžˆ μ‚΄νŽ΄λ³΄λ„λ‘ ν•˜μž.


0. JVM의 ꡬ동

Heap

νž™ μ˜μ—­μ€ μΈμŠ€ν„΄μŠ€ν™” 된 λͺ¨λ“  객체, 클래슀 λ°°μ—΄ 등을 μ €μž₯ν•˜λŠ” 곡간이며, μŠ€λ ˆλ“œλΌλ¦¬ κ³΅μœ κ°€ κ°€λŠ₯ν•˜λ‹€..
μ—¬κΈ°μ„œ ν• λ‹Ήλœ λ©”λͺ¨λ¦¬λŠ” λͺ…μ‹œμ μΈ λ°©λ²•μœΌλ‘œλŠ” μ ˆλŒ€ νšŒμˆ˜ν•˜μ§€ λͺ»ν•˜κ³  였직, Garbage Collector에 μ˜ν•΄ νšŒμˆ˜λœλ‹€.

Method Area

ν•„λ“œμ™€ λ©”μ„œλ“œ 데이터, μƒμ„±μž 및 λ©”μ†Œλ“œ μ½”λ“œ λ‚΄μš©, λŸ°νƒ€μž„ μƒμˆ˜ ν’€ 등을 μ €μž₯ν•˜λŠ” 곳이닀.
μ €μž₯λ˜λŠ” λ‚΄μš©μ˜ 경우 λ°”μ΄νŠΈμ½”λ“œμ˜ λ‚΄μš©κ³Ό 거의 μΌμΉ˜ν•˜λŠ”λ° μ΄λŠ” λ°”μ΄νŠΈμ½”λ“œμ— μƒμˆ˜ 풀을 ν¬ν•¨ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.
λ˜ν•œ, λŸ°νƒ€μž„ μƒμˆ˜ 풀은 μƒμˆ˜ 풀을 기반으둜 λ©”μ†Œλ“œ μ˜μ—­μ— μ €μž₯ν•  λ•Œ μƒμ„±λœλ‹€.

λ©”μ†Œλ“œ μ˜μ—­μ€ λ…Όλ¦¬μ μœΌλ‘œ νž™ μ˜μ—­μ˜ μΌλΆ€μ΄μ§€λ§Œ, μŠ€νŽ™μ—μ„œλŠ” 이 μœ„μΉ˜λ₯Ό κ°•μ œν•˜μ§€ μ•ŠλŠ”λ‹€.
즉, λ©”μ†Œλ“œ μ˜μ—­μ˜ μœ„μΉ˜λŠ” JVM을 μ–΄λ–»κ²Œ κ΅¬ν˜„ν•˜λŠλƒμ— 따라 λ‹¬λΌμ§ˆ 수 μžˆλ‹€.

OpenJDK에 μ‚¬μš©λ˜λŠ” Hotspot VM의 경우, 이 λ©”μ†Œλ“œ μ˜μ—­μ„ MetaspaceλΌλŠ” 이름을 μ‚¬μš©ν•˜μ—¬ κ΅¬ν˜„ν–ˆλ‹€.(JAVA 8 이상 λΆ€ν„°, κ·Έ μ΄μ „μ—λŠ” Permanent Area)


1. μ‹œμž‘ 클래슀의 생성

클래슀 λ‘œλ”

μ•žμ„œμ„œ μ‹œμž‘ 클래슀λ₯Ό λ©”λͺ¨λ¦¬μ— μ μž¬ν•˜λ©΄μ„œ μ‹œμž‘μ΄ λœλ‹€κ³  ν–ˆμ—ˆλ‹€.
이 μ‹œμž‘ 클래슀λ₯Ό λ‘œλ”©ν•˜λŠ” μ£Όμ²΄λŠ” 클래슀 λ‘œλ”μ΄λ©°, μ΄λŠ” JREμ—μ„œ 3가지 λ‚΄μž₯된 클래슀 λ‘œλ”(Bootstrap, Platform, System)λ₯Ό μ œκ³΅ν•œλ‹€.

μ‹œμž‘ ν΄λž˜μŠ€λŠ” μ‹œμŠ€ν…œ 클래슀 λ‘œλ”κ°€ λ‘œλ”©μ„ν•˜κ³ , μ‹œμŠ€ν…œ 클래슀 λ‘œλ”λŠ” ν”Œλž«νΌ 클래슀 λ‘œλ”κ°€, ν”Œλž«νΌ 클래슀 λ‘œλ”λŠ” λΆ€νŠΈμŠ€νŠΈλž© 클래슀 λ‘œλ”κ°€ λ‘œλ”©μ„ν•˜κ³  λΆ€νŠΈμŠ€νŠΈλž© 클래슀 λ‘œλ”λŠ” JREκ°€ 쑰성될 λ•Œ μ‹€ν–‰λœλ‹€.
즉, JRE μ‹€ν–‰ β†’ λΆ€νŠΈμŠ€νŠΈλž© β†’ ν”Œλž«νΌ β†’ μ‹œμŠ€ν…œ β†’ μ‹œμž‘ 클래슀 순으둜 싀행이 λ˜λŠ” 것이닀.

Run-Time Constant Pool

ν΄λž˜μŠ€κ°€ μƒμ„±λ˜λ©΄μ„œ λŸ°νƒ€μž„ μƒμˆ˜ 풀도 ν•¨κ»˜ μƒμ„±λœλ‹€.
μ΄κ³³μ—λŠ” μ»΄νŒŒμΌμ‹œμ— μ•Œ 수 μžˆλŠ” 숫자 λ¦¬ν„°λŸ΄ κ°’λΆ€ν„° λŸ°νƒ€μž„μ‹œμ— ν•΄μ„λ˜λŠ” λ©”μ†Œλ“œμ™€ ν•„λ“œ μ°Έμ‘°κΉŒμ§€ μ—¬λŸ¬ μ’…λ₯˜μ˜ μƒμˆ˜κ°€ μ €μž₯λœλ‹€.


2. 링크

클래슀/μΈν„°νŽ˜μ΄μŠ€μ˜ Super 클래슀/μΈν„°νŽ˜μ΄μŠ€, λ˜λŠ” λ°°μ—΄μ˜ μ›μ†Œμ˜ 클래슀/μΈν„°νŽ˜μ΄μŠ€λ₯Ό 확인, μ€€λΉ„ν•˜κ³  심볼릭 μ°Έμ‘°λ₯Ό ν•΄μ„ν•˜λŠ” 과정을 링크라고 ν•œλ‹€.
μ‰½κ²Œ λ§ν•˜μžλ©΄, μ½”λ“œ 쀑간에 λ‹€λ₯Έ 클래슀λ₯Ό μ°Έμ‘°ν•  일이 생겼을 λ•Œ ν•΄λ‹Ή 클래슀λ₯Ό λ‘œλ“œν•˜κΈ° μœ„ν•œ 과정이라고 보면 λœλ‹€.

  • 확인(Verification)

    클래슀 ν˜Ήμ€ μΈν„°νŽ˜μ΄μŠ€μ˜ λ°”μ΄λ„ˆλ¦¬ ν‘œν˜„μ΄ ꡬ쑰적으둜 μ˜¬λ°”λ₯Έμ§€λ₯Ό 보μž₯ν•΄μ£ΌλŠ” κ³Όμ •

  • μ€€λΉ„(Preparing)

    ν΄λž˜μŠ€λ‚˜ μΈν„°νŽ˜μ΄μŠ€μ˜ 정적(Static) ν•„λ“œλ₯Ό μƒμ„±ν•˜κ³  κΈ°λ³Έκ°’μœΌλ‘œ μ΄ˆκΈ°ν™”ν•˜λŠ” κ³Όμ •
    기본값이 μ•„λ‹Œ νŠΉμ •κ°’μœΌλ‘œ 정적 ν•„λ“œλ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” 것은 ν•΄λ‹Ή 과정이 μ•„λ‹Œ μ΄ˆκΈ°ν™” κ³Όμ •μ—μ„œ λ”°λ‘œ 처리

  • 해석(Resolution)

    λŸ°νƒ€μž„ μƒμˆ˜ 풀에 μžˆλŠ” 심볼릭 μ°Έμ‘°κ°€ ꡬ체적인 값을 가리킀도둝 λ™μ μœΌλ‘œ 결정을 ν•˜λŠ” κ³Όμ •

JVM μŠ€νŽ™μ—μ„œ 링크 과정이 μ–Έμ œ μ‹€ν–‰λ˜μ•Ό ν•œλ‹€λŠ” λͺ…ν™•ν•œ κ·œμ •μ„ ν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— JVM κ΅¬ν˜„μ²΄λ§ˆλ‹€ λ‹¬λΌμ§ˆ 수 μžˆλ‹€.
지연(lazy) 링크 μ „λž΅μ„ μ‚¬μš©ν•˜λŠ” 경우 클래슀/μΈν„°νŽ˜μ΄μŠ€μ— ν¬ν•¨λœ 심볼릭 μ°Έμ‘°λŠ” μ‹€μ œ μ°Έμ‘°κ°€ μ‚¬μš©λ  λ•Œ κ°œλ³„μ μœΌλ‘œ ν•΄μ„λ˜μ§€λ§Œ(μ΄ˆκΈ°ν™” 과정을 거친 후에 해석이 될 수 있음), μ¦‰μ‹œ(eager) 링크 μ „λž΅μ˜ 경우 클래슀/μΈν„°νŽ˜μ΄μŠ€κ°€ 확인 될 λ•Œ λͺ¨λ“  심볼릭 μ°Έμ‘°κ°€ ν•΄μ„λœλ‹€.


3. μ΄ˆκΈ°ν™”

μ΄ˆκΈ°ν™”(Initialization)λŠ” 클래슀/μΈν„°νŽ˜μ΄μŠ€μ˜ μ΄ˆκΈ°ν™” λ©”μ†Œλ“œλ₯Ό μ‹€ν–‰ν•  λ•Œ μˆ˜ν–‰λ˜λŠ” 과정이닀.
μ΄κ³³μ—μ„œ μ΄ˆκΈ°ν™”λŠ” "정적(Static) μ΄ˆκΈ°ν™”λ₯Ό ν•œλ‹€."라고 ν•  수 μžˆλ‹€.

μ΄ˆκΈ°ν™” λ©”μ†Œλ“œ

μ΄ˆκΈ°ν™” λ©”μ„œλ“œμ—λŠ” μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™” λ©”μ†Œλ“œ, 클래슀/μΈν„°νŽ˜μ΄μŠ€ μ΄ˆκΈ°ν™” λ©”μ„œλ“œκ°€ μ‘΄μž¬ν•œλ‹€.

  • μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™” λ©”μ†Œλ“œ

    μš°λ¦¬κ°€ 클래슀 내뢀에 μ„ μ–Έν•˜λŠ” μƒμ„±μžκ°€ 이에 ν•΄λ‹Ήν•˜λ©°, ν΄λž˜μŠ€λŠ” 0개 μ΄μƒμ˜ μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™” λ©”μ„œλ“œλ₯Ό 가지고 μžˆλ‹€.
    μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™” λ©”μ†Œλ“œλŠ” λ‹€μŒκ³Ό 같은 쑰건을 μΆ©μ‘±ν•΄μ•Ό λœλ‹€.

    • 클래슀 μ•ˆμ— μ •μ˜
    • λ°”μ΄νŠΈμ½”λ“œ μƒμ—μ„œ <init>μ΄λΌλŠ” νŠΉμˆ˜ν•œ μ΄λ¦„μœΌλ‘œ ν‘œν˜„
    • λ°˜ν™˜ νƒ€μž…μ€ void

    μΈμŠ€ν„΄μŠ€ μ΄ˆκΈ°ν™” λ©”μ†Œλ“œλŠ” νž™μ— μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” 역할을 ν•˜κ³ , 클래슀/μΈν„°νŽ˜μ΄μŠ€ μ΄ˆκΈ°ν™” λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€.

  • 클래슀/μΈν„°νŽ˜μ΄μŠ€ μ΄ˆκΈ°ν™” λ©”μ†Œλ“œ

    μ•žμ„  링크 λ‹¨κ³„μ—μ„œ νŠΉμ •κ°’μœΌλ‘œ 정적 ν•„λ“œλ₯Ό μ΄ˆκΈ°ν™” ν•˜κΈ° μœ„ν•΄μ„œλŠ” λ”°λ‘œ μ²˜λ¦¬ν•œλ‹€κ³  언급을 ν–ˆμ—ˆλŠ”λ°, ν•΄λ‹Ή λ©”μ†Œλ“œκ°€ κ·Έ 역할을 λ§‘μ•„μ„œ ν•œλ‹€.

    이 λ©”μ†Œλ“œλŠ” 클래슀/μΈν„°νŽ˜μ΄μŠ€μ— 1개만 μ‘΄μž¬ν•  수 있으며 λ‹€μŒκ³Ό 같은 쑰건을 μΆ©μ‘±ν•΄μ•Ό λœλ‹€.

    • λ°”μ΄νŠΈμ½”λ“œ μƒμ—μ„œ <clinit>μ΄λΌλŠ” νŠΉμˆ˜ν•œ μ΄λ¦„μœΌλ‘œ ν‘œν˜„
    • λ°˜ν™˜ νƒ€μž…μ€ void
    • class 파일 버전 51 μ΄μƒμ—μ„œλŠ” ACC_STATIC ν”Œλž˜κ·Έκ°€ λΆ™μŒ

    이 λ©”μ†Œλ“œλŠ” μŠ€νŽ™μ—μ„œλŠ” ꡬ체적인 μ„€λͺ…이 쑴재 ν•˜μ§€ μ•Šμ§€λ§Œ, static λΈ”λ‘λ“€μ˜ λ‚΄μš©μ„ ν•˜λ‚˜λ‘œ ν•©μΉœ 것이라고 λ³Ό 수 μžˆλ‹€.

    public class initializationTest {
      public final static int i ;
      static {
        i = 1;
      }
      public final static int j ;
      static {
        j = 2;
      }
    }
    
    /*
    λ°”μ΄νŠΈμ½”λ“œ 일뢀뢄
     static {};
        descriptor: ()V
        flags: ACC_STATIC
        Code:
          stack=1, locals=0, args_size=0
             0: iconst_1
             1: putstatic     #2                  // Field i:I
             4: iconst_2
             5: putstatic     #3                  // Field j:I
             8: return
          LineNumberTable:
            line 8: 0
            line 12: 4
            line 13: 8
    
    */

    μœ„μ™€ 같은 μ½”λ“œκ°€ μ‘΄μž¬ν•  λ•Œ, λ°”μ΄νŠΈμ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄λ©΄ ν•˜λ‚˜μ˜ λΈ”λŸ­(static{}) 으둜 λ³€κ²½λœ 것을 λ³Ό 수 μžˆλ‹€.


4. Main λ©”μ†Œλ“œ 호좜

이 μ‹œμ λΆ€ν„° μ‹€μ œ ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λœλ‹€.
ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λ˜κΈ° μœ„ν•΄ ν”„λ‘œκ·Έλž¨ νλ¦„μ˜ μ΅œμ†Œ λ‹¨μœ„μΈ μŠ€λ ˆλ“œκ°€ μ‘΄μž¬ν•΄μ•Ό 되며, JVMμ—μ„œλŠ” main() λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜κΈ° μœ„ν•΄ Main이 λ˜λŠ” μŠ€λ ˆλ“œλ₯Ό μƒμ„±ν•œλ‹€.
메인 μŠ€λ ˆλ“œκ°€ μƒμ„±λ˜λ©΄ PC λ ˆμ§€μŠ€ν„°, JVM μŠ€νƒ, λ„€μ΄ν‹°λΈŒ λ©”μ„œλ“œ μŠ€νƒμ΄ ν•¨κ»˜ μƒμ„±λœλ‹€.

PC Register

PC λ ˆμ§€μŠ€ν„°λŠ” ν˜„μž¬ 싀행쀑인 λ©”μ†Œλ“œκ°€ λ„€μ΄ν‹°λΈŒ λ©”μ†Œλ“œκ°€ μ•„λ‹ˆλ©΄ ν˜„μž¬ μ‹€ν–‰ 쀑인 JVM λͺ…λ Ήμ–΄μ˜ μœ„μΉ˜κ°€ μ €μž₯되고, λ„€μ΄ν‹°λΈŒ λ©”μ†Œλ“œμΌ 경우 μ €μž₯λ˜λŠ” 값은 μ •μ˜ λ˜μ§€ μ•ŠλŠ”λ‹€(undefined).

JVM Stack

JVM μŠ€νƒμ€ μ΄λ¦„μ—μ„œ μ•Œ 수 μžˆλ“―μ΄ LIFO λ°©μ‹μœΌλ‘œ λ™μž‘ν•˜λ©° ν”„λ ˆμž„(Frame)μ΄λΌλŠ” λ‹¨μœ„λ‘œ μ €μž₯이 λœλ‹€.

Frame

ν”„λ ˆμž„μ€ λ°μ΄ν„°λ‚˜ 쀑간 결과의 μ €μž₯, 동적 링크, κ°’ λ°˜ν™˜, μ˜ˆμ™Έ λ””μŠ€νŒ¨μΉ˜μ— μ‚¬μš©λœλ‹€.
즉, λ©”μ†Œλ“œκ°€ 호좜될 λ•Œλ§ˆλ‹€ μƒˆ ν”„λ ˆμž„μ΄ μƒμ„±λ˜μ–΄ μŠ€νƒμ— μŒ“μ΄κ³ , λ©”μ†Œλ“œ 호좜이 μ •μƒμ μœΌλ‘œ μ™„λ£Œ λ˜κ±°λ‚˜ μ˜ˆμ™Έκ°€ λ˜μ Έμ§€λ©΄ ν”„λ ˆμž„μ€ μŠ€νƒμ—μ„œ 빠지며 μ†Œλ©Έλœλ‹€.
ν”„λ ˆμž„μ€ 둜컬 λ³€μˆ˜ λ°°μ—΄, μ˜€νΌλžœλ“œ μŠ€νƒ, ν•΄λ‹Ή λ©”μ„œλ“œκ°€ μ†ν•œ 클래슀의 λŸ°νƒ€μž„ μƒμˆ˜ 풀에 λŒ€ν•œ 참쑰둜 κ΅¬μ„±λœλ‹€.

  • Local Variables

    둜컬 λ³€μˆ˜ λ°°μ—΄μ˜ ν¬κΈ°λŠ” 컴파일 νƒ€μž„μ— κ²°μ •λ˜λ©°, λ°”μ΄νŠΈμ½”λ“œμ—μ„œ Code 속성에 locals둜 ν‘œμ‹œλœλ‹€.
    longκ³Ό double의 경우 2개의 μŠ¬λ‘―μ— 걸쳐 μ €μž₯되고 λ‚˜λ¨Έμ§€λŠ” 1개의 μŠ¬λ‘―μ— μ €μž₯λœλ‹€.

    λ©”μ†Œλ“œκ°€ 클래슀 λ©”μ†Œλ“œμΌ 경우, μΈμžλŠ” 0번 μŠ¬λ‘―λΆ€ν„° μ°¨λ‘€λŒ€λ‘œ μ €μž₯λœλ‹€.
    μΈμŠ€ν„΄μŠ€ λ©”μ†Œλ“œμΌ κ²½μš°μ—λŠ” thisκ°€ 0번 슬둯, μΈμžλ“€μ΄ 1번 μŠ¬λ‘―λΆ€ν„° μ°¨λ‘€λŒ€λ‘œ μ €μž₯λœλ‹€.
    λ‚˜λ¨Έμ§€ 지역 λ³€μˆ˜λ“€μ΄ λ‚˜λ¨Έμ§€ μŠ¬λ‘―μ— μ €μž₯λœλ‹€.

  • Operand Stack

    μ˜€νΌλžœλ“œ μŠ€νƒμ˜ μ΅œλŒ€ κΉŠμ΄λŠ” 컴파일 νƒ€μž„μ— κ²°μ •λ˜κ³  λΉ„μ–΄μžˆλŠ” μƒνƒœλ‘œ μƒμ„±λ˜λ©°, λ°”μ΄νŠΈμ½”λ“œμ—μ„œ Code 속성에 stack으둜 ν‘œμ‹œλœλ‹€.
    λ©”μ†Œλ“œμ— μ „λ‹¬λ˜λŠ” νŒŒλΌλ―Έν„°λ₯Ό μ€€λΉ„ν•˜κ±°λ‚˜ λ©”μ†Œλ“œκ°€ λ°˜ν™˜ν•˜λŠ” 결과값을 받을 λ•Œ λ“± 거의 λͺ¨λ“  κ³Όμ •μ—μ„œ μ˜€νΌλžœλ“œ μŠ€νƒμ΄ μ‚¬μš©λœλ‹€.

  • Reference To Run-Time Constant Pool

    이름 κ·ΈλŒ€λ‘œ ν•΄λ‹Ή ν”„λ ˆμž„μ— λŒ€μ‘λ˜λŠ” λ©”μ†Œλ“œκ°€ μ†ν•œ 클래슀의 λŸ°νƒ€μž„ μƒμˆ˜ 풀에 λŒ€ν•œ μ°Έμ‘°λ₯Ό μ˜λ―Έν•œλ‹€.

Native Method Stack

보톡 C μŠ€νƒμ΄λΌκ³  λΆ€λ₯΄λ©°, μžλ°”κ°€ μ•„λ‹Œ λ‹€λ₯Έ μ–Έμ–΄λ‘œ μž‘μ„±λœ λ„€μ΄ν‹°λΈŒ λ©”μ†Œλ“œλ₯Ό μ§€μ›ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ˜λŠ” μŠ€νƒμ΄λ‹€.
JVM이 λ°˜λ“œμ‹œ λ„€μ΄ν‹°λΈŒ λ©”μ†Œλ“œλ₯Ό μ§€μ›ν•˜λŠ” 것이 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— λ„€μ΄ν‹°λΈŒ λ©”μ†Œλ“œ μŠ€νƒ μ—­μ‹œ ν•„μˆ˜λŠ” μ•„λ‹ˆλ‹€.

Main λ©”μ†Œλ“œ μ‹€ν–‰

μƒμ„±λœ λ°”μ΄νŠΈ μ½”λ“œμ— μžˆλŠ” λͺ…령어에 따라 μ—¬νƒœ μƒμ„±λœ 정보듀을 가지고 λ©”μ†Œλ“œλ₯Ό μƒμ„±ν•œλ‹€.
λ’€νƒœμ§€μ‘΄λ‹˜μ΄ λ“€μ–΄μ£Όμ‹  μ λ‹Ήν•œ μ˜ˆμ‹œκ°€ μžˆκΈ°μ— 그것을 λ³΄λ©΄μ„œ μ–΄λ–»κ²Œ μ‹€ν–‰λ˜λŠ”μ§€ 보면 쒋을것 κ°™λ‹€.(그림도 μžˆμ–΄ μ΄ν•΄ν•˜κΈ° νŽΈν•¨)