Post

[Java] JVM

[Java] JVM

πŸ“Œ JVMμ΄λž€?

JVM(Java Virtual Machine) 은 μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‹€ν–‰ν•˜κΈ° μœ„ν•œ 가상 λ¨Έμ‹ μœΌλ‘œ μžλ°” λ°”μ΄νŠΈμ½”λ“œ(.class)λ₯Ό 운영 μ²΄μ œμ™€ ν•˜λ“œμ›¨μ–΄μ— λ…λ¦½μ μœΌλ‘œ μ‹€ν–‰ν•  수 μžˆλ„λ‘ ν•˜λŠ” μ†Œν”„νŠΈμ›¨μ–΄ 계측이닀. 즉, JVM이 μ„€μΉ˜λœ OSμ—μ„œλŠ” λ³„λ„μ˜ μž‘μ—… 없이 μžλ°”λ‘œ μž‘μ„±λœ ν”„λ‘œκ·Έλž¨(.java)을 μ‹€ν–‰ν•  수 μžˆλ‹€.

πŸ“Œ λ™μž‘ 방식

image.png

  1. μžλ°” μ†ŒμŠ€ 파일(.java)λŠ” μžλ°” 컴파일러(javac)에 μ˜ν•΄ λ°”μ΄νŠΈμ½”λ“œ(.class)둜 λ³€ν™˜λœλ‹€.
  2. λ³€ν™˜λœ λ°”μ΄νŠΈμ½”λ“œλŠ” JVM의 클래슀 λ‘œλ”μ— μ˜ν•΄ λ©”λͺ¨λ¦¬λ‘œ λ‘œλ“œλœλ‹€.
  3. 클래슀 λ‘œλ”κ°€ λ‘œλ“œν•œ λ°”μ΄νŠΈμ½”λ“œλŠ” λŸ°νƒ€μž„ 데이터 μ˜μ—­μ— λ°°μΉ˜λœλ‹€.
  4. μ‹€ν–‰ 엔진이 λ°”μ΄νŠΈμ½”λ“œλ₯Ό ν•΄μ„ν•˜κ±°λ‚˜ JIT 컴파일러λ₯Ό 톡해 κΈ°κ³„μ–΄λ‘œ λ³€ν™˜ν•˜μ—¬ μ‹€ν–‰ν•œλ‹€.
  5. μ‹€ν–‰ 도쀑 ν•„μš” μ—†λŠ” κ°μ²΄λŠ” κ°€λΉ„μ§€ 컬렉터가 μ •λ¦¬ν•œλ‹€.

πŸ“Œ ꡬ성 μš”μ†Œ

Class Loader

  • Loading

JVM이 .class νŒŒμΌμ„ μ°Ύκ³  이λ₯Ό λŸ°νƒ€μž„ 데이터 μ˜μ—­μ— μ μž¬ν•œλ‹€. λ˜ν•œ 심볼릭 레퍼런슀(ν•„λ“œ, λ©”μ†Œλ“œ λ“±)λ₯Ό λŸ°νƒ€μž„ μƒμˆ˜ 풀에 λ³΅μ‚¬ν•œλ‹€.

  • Linking

λ‘œλ“œλœ ν΄λž˜μŠ€κ°€ μ‹€μ œλ‘œ 싀행될 수 μžˆλ„λ‘ μ€€λΉ„ν•˜λŠ” κ³Όμ •μœΌλ‘œ λ‹€μŒ ν•˜μœ„ λ‹¨κ³„λ‘œ λ‚˜λ‰œλ‹€.

  • Verification(검증): 클래슀 파일의 λ°”μ΄νŠΈμ½”λ“œκ°€ JVM λͺ…세에 λ§žλŠ”μ§€ ν™•μΈν•œλ‹€. ꡬ쑰적으둜 μ˜¬λ°”λ₯΄μ§€ μ•ŠλŠ” 경우 VerifyError κ°€ λ°œμƒν•œλ‹€.
  • Preparation(μ€€λΉ„): 클래슀의 static ν•„λ“œλ₯Ό μœ„ν•œ λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•˜κ³  κΈ°λ³Έκ°’μœΌλ‘œ μ΄ˆκΈ°ν™”ν•œλ‹€. λͺ…μ‹œμ  μ΄ˆκΈ°ν™”λŠ” 아직 이루어지지 μ•ŠλŠ”λ‹€.
  • Resolution(ν•΄κ²°): Loading λ‹¨κ³„μ—μ„œ λ³΅μ‚¬ν•œ 심볼릭 레퍼런슀λ₯Ό μ‹€μ œ λ©”λͺ¨λ¦¬ μ£Όμ†Œλ‘œ λ³€ν™˜ν•œλ‹€.
  • Initialization

클래슀의 <clinit> λ©”μ†Œλ“œκ°€ ν˜ΈμΆœλ˜μ–΄ static λ³€μˆ˜μ˜ λͺ…μ‹œμ  μ΄ˆκΈ°ν™”μ™€ static 블둝이 ν•œ 번만 μ‹€ν–‰λœλ‹€.

Execution Engine

Execution Engineμ—μ„œ λ°”μ΄νŠΈμ½”λ“œκ°€ μ‹€μ œλ‘œ μ‹€ν–‰λœλ‹€.

  • Interpreter

JVM이 λ°”μ΄νŠΈμ½”λ“œλ₯Ό λͺ…λ Ήμ–΄ λ‹¨μœ„λ‘œ ν•˜λ‚˜μ”© 읽고 ν•΄μ„ν•˜μ—¬ μ‹€ν–‰ν•˜λŠ” 방식이닀. 이 방식은 JVM이 μ‹œμž‘λ  λ•Œ λΉ λ₯Έ 싀행이 κ°€λŠ₯ν•˜λ„λ‘ ν•˜μ§€λ§Œ, 같은 λ©”μ†Œλ“œκ°€ 반볡적으둜 호좜될 λ•Œλ§ˆλ‹€ 맀번 해석해야 ν•˜λ―€λ‘œ μ‹€ν–‰ 속도가 λŠλ¦¬λ‹€.

  • JIT(Just-In-Time) Compiler

Interpreter의 μ„±λŠ₯ μ €ν•˜ 문제λ₯Ό λ³΄μ™„ν•˜κΈ° μœ„ν•΄ λ„μž…λ˜μ—ˆλ‹€. JVM은 μ²˜μŒμ—λŠ” Interpreter λ°©μ‹μœΌλ‘œ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λ‹€κ°€ νŠΉμ • λ©”μ†Œλ“œκ°€ 반볡적으둜 ν˜ΈμΆœλ˜λŠ” Hotspot 이 κ°μ§€λ˜λ©΄ ν•΄λ‹Ή λ°”μ΄νŠΈμ½”λ“œ 전체λ₯Ό κΈ°κ³„μ–΄λ‘œ μ»΄νŒŒμΌν•œλ‹€. 이후 기계어λ₯Ό μΊμ‹œμ— μ €μž₯ν•œ ν›„, 같은 λ©”μ†Œλ“œκ°€ λ‹€μ‹œ 호좜될 λ•Œ μΊμ‹±λœ 기계어λ₯Ό 읽어 λ°”λ‘œ μ‹€ν–‰ν•œλ‹€.

  • Garbage Collector

JVM의 μ‹€ν–‰ μ—”μ§„μ—μ„œ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 객체λ₯Ό νƒμ§€ν•˜μ—¬ νž™ λ©”λͺ¨λ¦¬μ—μ„œ μ œκ±°ν•œλ‹€. 이λ₯Ό 톡해 λ©”λͺ¨λ¦¬ λˆ„μˆ˜ 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€.

Runtime Data Area

μžλ°” ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ μ‹œ 운영 μ²΄μ œλ‘œλΆ€ν„° ν• λ‹Ήλ°›λŠ” λ©”λͺ¨λ¦¬ μ˜μ—­μœΌλ‘œ ν”„λ‘œκ·Έλž¨μ˜ 데이터와 μ‹€ν–‰ 정보λ₯Ό μ €μž₯ν•˜κ³  κ΄€λ¦¬ν•œλ‹€.

  • PC Register

각 μ“°λ ˆλ“œλ§ˆλ‹€ λ…λ¦½μ μœΌλ‘œ μƒμ„±λ˜λŠ” λ©”λͺ¨λ¦¬ κ³΅κ°„μœΌλ‘œ ν˜„μž¬ μ‹€ν–‰ 쀑인 JVM λͺ…λ Ήμ–΄μ˜ μ£Όμ†Œλ₯Ό μ €μž₯ν•œλ‹€. 이 μ˜μ—­μ€ μ“°λ ˆλ“œκ°€ μ‹œμž‘λ  λ•Œ ν• λ‹Ήλ˜κ³  μ’…λ£Œ μ‹œ ν•΄μ œλœλ‹€.

  • JVM Stacks

각 μ“°λ ˆλ“œλ§ˆλ‹€ λ…λ¦½μ μœΌλ‘œ μƒμ„±λ˜λŠ” λ©”λͺ¨λ¦¬ κ³΅κ°„μœΌλ‘œ λ©”μ†Œλ“œ 호좜 μ‹œλ§ˆλ‹€ μŠ€νƒ ν”„λ ˆμž„μ΄ μŒ“μΈλ‹€. 각 μŠ€νƒ ν”„λ ˆμž„μ—λŠ” λ©”μ†Œλ“œμ˜ μ§€μ—­ λ³€μˆ˜, λ§€κ°œλ³€μˆ˜, 리턴값, μ—°μ‚° 쀑간값 등이 μ €μž₯λœλ‹€. λ©”μ†Œλ“œκ°€ 호좜되면 ν”„λ ˆμž„μ΄ push되며, μ’…λ£Œλ˜λ©΄ popλœλ‹€. μŠ€νƒ κ΅¬μ‘°μ΄λ―€λ‘œ LIFO ꡬ쑰둜 λ™μž‘ν•˜λ©° μŠ€νƒ 크기λ₯Ό μ΄ˆκ³Όν•˜λ©΄ StackOverflowError κ°€ λ°œμƒν•œλ‹€. 이 μ˜μ—­μ€ μ“°λ ˆλ“œ κ°„ κ³΅μœ ν•˜μ§€ μ•ŠλŠ”λ‹€.

  • Native Method Stacks

μžλ°”κ°€ μ•„λ‹Œ λ„€μ΄ν‹°λΈŒ μ½”λ“œ(C++, C, μ–΄μ…ˆλΈ”λ¦¬ λ“±)둜 μž‘μ„±λœ λ©”μ†Œλ“œλ₯Ό μ‹€ν–‰ν•  λ•Œ μ‚¬μš©ν•˜λŠ” μŠ€νƒμ΄λ‹€. μ—­μ‹œ 각 μ“°λ ˆλ“œλ§ˆλ‹€ λ…λ¦½μ μœΌλ‘œ ν• λ‹Ήλ˜λ©° μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ JNI(Java Native Interface) λ₯Ό 톡해 λ„€μ΄ν‹°λΈŒ λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œ 이 μŠ€νƒμ΄ ν™œμš©λœλ‹€.

  • Heap

JVM이 μ‹œμž‘λ  λ•Œ μƒμ„±λ˜λ©° λͺ¨λ“  μ“°λ ˆλ“œκ°€ κ³΅μœ ν•˜λŠ” λ©”λͺ¨λ¦¬ 곡간이닀. new ν‚€μ›Œλ“œλ₯Ό 톡해 λ™μ μœΌλ‘œ μƒμ„±λœ 객체 λ˜λŠ” 배열이 μ €μž₯λœλ‹€. 객체의 μ‹€μ œ λ°μ΄ν„°λŠ” νž™μ— μ €μž₯되고 참쑰값은 JVM Stack에 μ €μž₯λœλ‹€. νž™μ€ κ°€λΉ„μ§€ μ»¬λ ‰μ…˜μ˜ λŒ€μƒμ΄ λœλ‹€. νž™μ΄ 가득 μ°¨λ©΄ OutOfMemoryError κ°€ λ°œμƒν•œλ‹€.

  • Method Area

ν΄λž˜μŠ€μ— λŒ€ν•œ λͺ¨λ“  정보(메타데이터, λ°”μ΄νŠΈμ½”λ“œ, μƒμˆ˜ ν’€, static λ³€μˆ˜ λ“±)κ°€ μ €μž₯λ˜λŠ” μ˜μ—­μœΌλ‘œ λͺ¨λ“  μ“°λ ˆλ“œκ°€ κ³΅μœ ν•œλ‹€. JVM이 클래슀λ₯Ό λ‘œλ”©ν•˜λ©΄ κ·Έ 정보가 λ©”μ†Œλ“œ μ˜μ—­μ— μ μž¬λœλ‹€. 이 μ˜μ—­μ€ JVM이 μ‹œμž‘λ˜λ©΄ μƒμ„±λ˜λ©° ν”„λ‘œκ·Έλž¨μ΄ μ’…λ£Œλ  λ•ŒκΉŒμ§€ μœ μ§€λœλ‹€. 이 μ˜μ—­μ΄ 가득 μ°¨λ©΄ OutOfMemoryError κ°€ λ°œμƒν•œλ‹€.

πŸ“Œ JDK vs. JRE vs. JVM

image.png

JDK(Java Development Kit)

JDK λŠ” μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ°œλ°œν•˜κΈ° μœ„ν•œ μ†Œν”„νŠΈμ›¨μ–΄ 개발 ν‚€νŠΈμ΄λ‹€. JDK에 JRE, 컴파일러, 디버거, JavaDoc 등이 ν¬ν•¨λ˜μ–΄ μžˆλ‹€. 즉, κ°œλ°œμžλŠ” JDKλ₯Ό μ‚¬μš©ν•˜μ—¬ μžλ°” μ†ŒμŠ€ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κ³  컴파일 및 디버깅할 수 μžˆλ‹€.

JRE(Java Runtime Environment )

JRE λŠ” μžλ°” ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•  수 μžˆλŠ” ν™˜κ²½μ„ μ œκ³΅ν•˜λŠ” νŒ¨ν‚€μ§€μ΄λ‹€. JVMκ³Ό ν”„λ‘œκ·Έλž¨ 싀행에 ν•„μš”ν•œ 라이브러리, λ¦¬μ†ŒμŠ€ 파일 등을 ν¬ν•¨ν•œλ‹€. 컴파일러, 디버거같은 개발 λ„κ΅¬λŠ” ν¬ν•¨ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ°œλ°œν•  μˆ˜λŠ” μ—†λ‹€.

JVM(Java Virtual Machine)

JVM 은 μžλ°” λ°”μ΄νŠΈμ½”λ“œ(.class)λ₯Ό 운영 μ²΄μ œμ™€ ν•˜λ“œμ›¨μ–΄μ— λ…λ¦½μ μœΌλ‘œ μ‹€ν–‰ν•  수 μžˆλ„λ‘ ν•˜λŠ” μ†Œν”„νŠΈμ›¨μ–΄ 계측이닀. 즉, JVM이 μ„€μΉ˜λœ OSμ—μ„œλŠ” λ³„λ„μ˜ μž‘μ—… 없이 μžλ°”λ‘œ μž‘μ„±λœ ν”„λ‘œκ·Έλž¨(.java)을 μ‹€ν–‰ν•  수 μžˆλ‹€. JVM은 JRE에 ν¬ν•¨λ˜λ©° κ°œλ°œμžκ°€ 직접 JVM을 λ‹€λ£¨λŠ” 것이 μ•„λ‹Œ μžλ°” ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λ˜λ©΄ λ‚΄λΆ€μ μœΌλ‘œ λ™μž‘ν•œλ‹€.

즉, JDK μ•ˆμ— JREκ°€ 있고, JRE μ•ˆμ— JVM이 μžˆλ‹€.

πŸ“Œ μ°Έκ³ 

https://inpa.tistory.com/entry/JAVA-%E2%98%95-JVM-%EB%82%B4%EB%B6%80-%EA%B5%AC%EC%A1%B0-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EC%98%81%EC%97%AD-%EC%8B%AC%ED%99%94%ED%8E%B8#%EC%9E%90%EB%B0%94%EA%B0%80%EC%83%81%EB%A8%B8%EC%8B%A0jvm%EC%9D%98%EB%8F%99%EC%9E%91%EB%B0%A9%EC%8B%9D

https://lsj31404.tistory.com/105

https://inpa.tistory.com/entry/JAVA-%E2%98%95-JDK-JRE-JVM-%EA%B0%9C%EB%85%90-%EA%B5%AC%EC%84%B1-%EC%9B%90%EB%A6%AC-%F0%9F%92%AF-%EC%99%84%EB%B2%BD-%EC%B4%9D%EC%A0%95%EB%A6%AC

https://www.boardinfinity.com/blog/understanding-the-difference-between-jdk-jre-and-jvm/

This post is licensed under CC BY 4.0 by the author.