πŸ’» [Theory] JVM(Java Virtual Machine)의 ꡬ쑰

πŸ’» [Theory] JVM(Java Virtual Machine)의 ꡬ쑰

μ•ˆλ…•ν•˜μ„Έμš”. πŸ‘‹

μ˜€λŠ˜μ€ JVM(Java Virtual Machine)의 ꡬ쑰에 λŒ€ν•΄ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

JVM(Java Virtual Machine) μ΄λž€?

JVM μ΄λž€ μžλ°” 가상 λ¨Έμ‹ μœΌλ‘œ Java λ°”μ΄νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 μžˆλŠ” 주체이닀.

νŠΉνžˆλ‚˜ CPUλ‚˜ 운영체제(ν”Œλž«νΌ)의 μ’…λ₯˜μ™€ λ¬΄κ΄€ν•˜κ²Œ 싀행이 κ°€λŠ₯ν•˜λ‹€. -> μžλ°”λ₯Ό μ‚¬μš©ν•˜λŠ” 이유이자 μž₯점에 ν•΄λ‹Ήν•œλ‹€.

즉, 운영체제 μœ„μ—μ„œ λ™μž‘ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€λ‘œ μžλ°” μ½”λ“œλ₯Ό μ»΄νŒŒμΌν•΄μ„œ 얻은 λ°”μ΄νŠΈ μ½”λ“œλ₯Ό ν•΄λ‹Ή μš΄μ˜μ²΄μ œκ°€ 이해할 수 μžˆλŠ” κΈ°κ³„μ–΄λ‘œ λ°”κΏ” μ‹€ν–‰μ‹œμΌœμ£ΌλŠ” 역할을 ν•œλ‹€.

JVM의 ꡬ성을 μ‚΄νŽ΄λ³΄λ©΄ 크게 4가지(Class Loader, Execution Engine, Garbage Collector, Runtime Data Area)둜 λ‚˜λ‰œλ‹€.

jvm-structure

  1. Class Loader (클래슀 λ‘œλ”)

μžλ°”μ—μ„œ μ†ŒμŠ€λ₯Ό μž‘μ„±ν•˜λ©΄ Person.java 처럼 .java 파일이 μƒμ„±λœλ‹€.

.java μ†ŒμŠ€λ₯Ό μžλ°”μ»΄νŒŒμΌλŸ¬κ°€ μ»΄νŒŒμΌν•˜λ©΄ Person.class 같은 .class파일(λ°”μ΄νŠΈμ½”λ“œ)이 μƒμ„±λœλ‹€.

μ΄λ ‡κ²Œ μƒμ„±λœ 클래슀 νŒŒμΌλ“€μ„ λΆ„μ„ν•œ 뒀에 JVM이 μš΄μ˜μ²΄μ œλ‘œλΆ€ν„° 할당받은 λ©”λͺ¨λ¦¬μ˜μ—­μΈ

Runtime Data Area둜 μ μž¬ν•˜λŠ” μ—­ν• (λŸ°νƒ€μž„ μ‹œ 동적 λ‘œλ”©)을 Class Loaderκ°€ ν•œλ‹€.

β€»μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ 싀행쀑일 λ•Œ 이런 μž‘μ—…μ΄ μˆ˜ν–‰λœλ‹€.

  1. Execution Engine (μ‹€ν–‰ 엔진)

Class Loader에 μ˜ν•΄ λ©”λͺ¨λ¦¬μ— 적재된 클래슀(λ°”μ΄νŠΈ μ½”λ“œ)듀을 κΈ°κ³„μ–΄λ‘œ λ³€κ²½ν•΄ λͺ…λ Ήμ–΄ λ‹¨μœ„λ‘œ μ‹€ν–‰ν•˜λŠ” 역할을 ν•œλ‹€.

λͺ…λ Ήμ–΄λ₯Ό ν•˜λ‚˜ ν•˜λ‚˜ μ‹€ν–‰ν•˜λŠ” 인터프리터(Interpreter)방식이 있고 JIT(Just-In-Time) 컴파일러λ₯Ό μ΄μš©ν•˜λŠ” 방식이 μžˆλ‹€.

JIT μ»΄νŒŒμΌλŸ¬λŠ” μ μ ˆν•œ μ‹œκ°„μ— 전체 λ°”μ΄νŠΈ μ½”λ“œλ₯Ό λ„€μ΄ν‹°λΈŒ μ½”λ“œλ‘œ λ³€κ²½ν•΄μ„œ Execution Engine이 λ„€μ΄ν‹°λΈŒλ‘œ 컴파일된 μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λŠ” κ²ƒμœΌλ‘œ μ„±λŠ₯을 λ†’μ΄λŠ” 방식이닀.

  • 인터프리터 방식 : λͺ…λ Ήμ–΄λ₯Ό ν•˜λ‚˜μ”© μˆ˜ν–‰(기본적인 방식. 전체 μˆ˜ν–‰μ€ λŠλ¦¬λ‚˜ λͺ…λ Ήμ–΄ ν•˜λ‚˜μ”©μ˜ λ™μž‘μ€ 빠름)
  • JIT(Just In Time compiler)방식 : 전체 λ°”μ΄νŠΈ μ½”λ“œλ₯Ό λ„€μ΄ν‹°λΈŒ μ½”λ“œλ‘œ λ³€ν™˜ν•˜κ³  κ·Έ μ΄ν›„μ—λŠ” μΈν„°ν”„λ¦¬νŒ…ν•˜μ§€ μ•Šκ³  λ„€μ΄ν‹°λΈŒ μ½”λ“œ μƒνƒœλ‘œ μ‹€ν–‰(전체적인 λ™μž‘μ€ λΉ λ₯΄λ‚˜ μ»΄νŒŒμΌν•˜λŠ”λ° 상당 μ‹œκ°„ μ†Œμš”)

졜초의 가상 머신은 인터프리터 λ°©μ‹λ§Œ μ¨μ„œ μ‹€ν–‰ 속도가 λŠλ Έμ§€λ§Œ, JIT 컴파일 방식을 μΆ”κ°€ν•˜μ—¬ 이λ₯Ό λ³΄μ™„ν•˜κ³ μž ν–ˆλ‹€. 그런데 JIT μ»΄νŒŒμΌμ€ λ°”μ΄νŠΈμ½”λ“œλ₯Ό κΈ°κ³„μ–΄λ‘œ λ°”κΎΈκΈ° λ•Œλ¬Έμ— μ‹€ν–‰ 속도가 λΉ λ₯΄μ§€λ§Œ λ³€ν™˜ν•˜λŠ” 데 λΉ„μš©μ΄ λ°œμƒν•˜κ²Œ λœλ‹€. κ·Έλž˜μ„œ 인터프리터 방식을 μ‚¬μš©ν•˜λ‹€κ°€ μΌμ •ν•œ 기쀀이 λ„˜μ–΄κ°€λ©΄ JIT 컴파일 λ°©μ‹μœΌλ‘œ μ‹€ν–‰ν•œλ‹€.

  1. Garbage Collector (가비지 컬렉터)

Garbage Collector(GC)λŠ” Heap λ©”λͺ¨λ¦¬ μ˜μ—­μ— 생성(적재)된 객체듀 쀑에 μ°Έμ‘°λ˜μ§€ μ•ŠλŠ” 객체듀을 탐색 ν›„ μ œκ±°ν•˜λŠ” 역할을 ν•œλ‹€.

GCκ°€ 역할을 ν•˜λŠ” μ‹œκ°„μ€ μ •ν™•νžˆ μ–Έμ œμΈμ§€λ₯Ό μ•Œ 수 μ—†λ‹€. (μ°Έμ‘°κ°€ μ—†μ–΄μ§€μžλ§ˆμž ν•΄μ œλ˜λŠ” 것을 보μž₯ν•˜μ§€ μ•ŠμŒ)

또 λ‹€λ₯Έ νŠΉμ§•μ€ GCκ°€ μˆ˜ν–‰λ˜λŠ” λ™μ•ˆ GCλ₯Ό μˆ˜ν–‰ν•˜λŠ” μ“°λ ˆλ“œκ°€ μ•„λ‹Œ λ‹€λ₯Έ λͺ¨λ“  μ“°λ ˆλ“œκ°€ μΌμ‹œμ •μ§€λœλ‹€.

특히 Full GCκ°€ μΌμ–΄λ‚˜μ„œ 수 μ΄ˆκ°„ λͺ¨λ“  μ“°λ ˆλ“œκ°€ μ •μ§€ν•œλ‹€λ©΄ μž₯μ• λ‘œ μ΄μ–΄μ§€λŠ” 치λͺ…적인 λ¬Έμ œκ°€ 생길 수 μžˆλŠ” 것이닀.

λ‚΄μš©μ΄ 많고 μ€‘μš”ν•œ λΆ€λΆ„μ΄λ―€λ‘œ λ‹€μŒ ν¬μŠ€νŠΈμ—μ„œ 더 μžμ„Ένžˆ λ‹€λ€„λ³΄μž

  1. Runtime Data Area (λŸ°νƒ€μž„ 데이터 μ˜μ—­)

JVM의 λ©”λͺ¨λ¦¬ μ˜μ—­μœΌλ‘œ μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‹€ν–‰ν•  λ•Œ μ‚¬μš©λ˜λŠ” 데이터듀을 μ μž¬ν•˜λŠ” μ˜μ—­μ΄λ‹€.

이 μ˜μ—­μ€ 크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack둜 λ‚˜λˆŒ 수 μžˆλ‹€.


##μžλ°” λŸ°νƒ€μž„ λ©”λͺ¨λ¦¬(Runtime Data area) ꡬ쑰

runtime-data-area-structure

1.Method area (λ©”μ†Œλ“œ μ˜μ—­)

클래슀 멀버 λ³€μˆ˜μ˜ 이름, 데이터 νƒ€μž…, μ ‘κ·Ό μ œμ–΄μž 정보같은 ν•„λ“œ 정보와 λ©”μ†Œλ“œμ˜ 이름, 리턴 νƒ€μž…, νŒŒλΌλ―Έν„°, μ ‘κ·Ό μ œμ–΄μž 정보같은 λ©”μ†Œλ“œ 정보,

Type정보(Interface인지 class인지), Constant Pool(μƒμˆ˜ ν’€ : 문자 μƒμˆ˜, νƒ€μž…, ν•„λ“œ, 객체 μ°Έμ‘°κ°€ μ €μž₯됨), static λ³€μˆ˜, final class λ³€μˆ˜λ“±μ΄ μƒμ„±λ˜λŠ” μ˜μ—­μ΄λ‹€.

ν΄λž˜μŠ€μ— λŒ€ν•œ 정보와 ν•¨κ»˜ 클래슀 λ³€μˆ˜(static variable)κ°€ μ €μž₯λ˜λŠ” μ˜μ—­.
JVM은 μžλ°” ν”„λ‘œκ·Έλž¨μ—μ„œ νŠΉμ • ν΄λž˜μŠ€κ°€ μ‚¬μš©λ˜λ©΄ ν•΄λ‹Ή 클래슀의 클래슀 파일(*.class)을 읽어듀여, ν΄λž˜μŠ€μ— λŒ€ν•œ 정보λ₯Ό λ©”μ†Œλ“œ μ˜μ—­μ— μ €μž₯ν•œλ‹€.
Class area (클래슀 μ˜μ—­)이라고도 ν•œλ‹€.

2.Heap area (νž™ μ˜μ—­)

λŸ°νƒ€μž„ μ‹œ κ²°μ •λ˜λŠ” μ°Έμ‘°ν˜• λ°μ΄ν„°νƒ€μž…μ΄ μ €μž₯λ˜λŠ” 곡간,

new ν‚€μ›Œλ“œλ‘œ μƒμ„±λœ 객체와 배열이 μƒμ„±λ˜λŠ” μ˜μ—­μ΄λ‹€.

λ©”μ†Œλ“œ μ˜μ—­μ— λ‘œλ“œλœ 클래슀만 생성이 κ°€λŠ₯ν•˜κ³  Garbage Collectorκ°€ μ°Έμ‘°λ˜μ§€ μ•ŠλŠ” λ©”λͺ¨λ¦¬λ₯Ό ν™•μΈν•˜κ³  μ œκ±°ν•˜λŠ” μ˜μ—­μ΄λ‹€.

3.Stack area (μŠ€νƒ μ˜μ—­)

컴파일 μ‹œ κ²°μ •λ˜λŠ” κΈ°λ³Έν˜• λ°μ΄ν„°νƒ€μž…μ΄ μ €μž₯λ˜λŠ” 곡간,

지역 λ³€μˆ˜, νŒŒλΌλ―Έν„°, 리턴 κ°’, 연산에 μ‚¬μš©λ˜λŠ” μž„μ‹œ 값등이 μƒμ„±λ˜λŠ” μ˜μ—­μ΄λ‹€.

int a = 10; μ΄λΌλŠ” μ†ŒμŠ€λ₯Ό μž‘μ„±ν–ˆλ‹€λ©΄ μ •μˆ˜κ°’μ΄ 할당될 수 μžˆλŠ” λ©”λͺ¨λ¦¬κ³΅κ°„을 a라고 μž‘μ•„λ‘κ³  κ·Έ λ©”λͺ¨λ¦¬ μ˜μ—­μ— 값이 10이 λ“€μ–΄κ°„λ‹€. 즉, μŠ€νƒμ— λ©”λͺ¨λ¦¬μ— 이름이 a라고 λΆ™μ—¬μ£Όκ³  값이 10인 λ©”λͺ¨λ¦¬ 곡간을 λ§Œλ“ λ‹€.

클래슀 Person p = new Person(); μ΄λΌλŠ” μ†ŒμŠ€λ₯Ό μž‘μ„±ν–ˆλ‹€λ©΄ Person pλŠ” μŠ€νƒ μ˜μ—­μ— μƒμ„±λ˜κ³  new둜 μƒμ„±λœ Person 클래슀의 μΈμŠ€ν„΄μŠ€λŠ” νž™ μ˜μ—­μ— μƒμ„±λœλ‹€.

그리고 μŠ€νƒμ˜μ—­μ— μƒμ„±λœ p의 κ°’μœΌλ‘œ νž™ μ˜μ—­μ˜ μ£Όμ†Œκ°’μ„ 가지고 μžˆλ‹€. 즉, μŠ€νƒ μ˜μ—­μ— μƒμ„±λœ pκ°€ νž™ μ˜μ—­μ— μƒμ„±λœ 객체λ₯Ό 가리킀고(μ°Έμ‘°ν•˜κ³ ) μžˆλŠ” 것이닀.

λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œλ§ˆλ‹€ κ°œλ³„μ μœΌλ‘œ μŠ€νƒμ΄ μƒμ„±λœλ‹€.

4.PC Register (PC λ ˆμ§€μŠ€ν„°)

Thread(μ“°λ ˆλ“œ)κ°€ 생성될 λ•Œλ§ˆλ‹€ μƒμ„±λ˜λŠ” μ˜μ—­μœΌλ‘œ Program Counter 즉, ν˜„μž¬ μ“°λ ˆλ“œκ°€ μ‹€ν–‰λ˜λŠ” λΆ€λΆ„μ˜ μ£Όμ†Œμ™€ λͺ…령을 μ €μž₯ν•˜κ³  μžˆλŠ” μ˜μ—­μ΄λ‹€. (*CPU의 λ ˆμ§€μŠ€ν„°μ™€ 닀름)

이것을 μ΄μš©ν•΄μ„œ μ“°λ ˆλ“œλ₯Ό λŒμ•„κ°€λ©΄μ„œ μˆ˜ν–‰ν•  수 있게 ν•œλ‹€.

5.Native method stack

μžλ°” μ™Έ μ–Έμ–΄λ‘œ μž‘μ„±λœ λ„€μ΄ν‹°λΈŒ μ½”λ“œλ₯Ό μœ„ν•œ λ©”λͺ¨λ¦¬ μ˜μ—­μ΄λ‹€.

보톡 C/C++λ“±μ˜ μ½”λ“œλ₯Ό μˆ˜ν–‰ν•˜κΈ° μœ„ν•œ μŠ€νƒμ΄λ‹€.

Java Native Interfaceλ₯Ό 톡해 λ°”μ΄νŠΈμ½”λ“œλ‘œ λ³€ν™˜λ¨

μ“°λ ˆλ“œκ°€ μƒμ„±λ˜μ—ˆμ„ λ•Œ κΈ°μ€€μœΌλ‘œ

1,2번인 λ©”μ†Œλ“œ μ˜μ—­κ³Ό νž™ μ˜μ—­μ„ λͺ¨λ“  μ“°λ ˆλ“œκ°€ κ³΅μœ ν•˜κ³ ,

3,4,5번인 μŠ€νƒ μ˜μ—­κ³Ό PC λ ˆμ§€μŠ€ν„°, Native method stack은 각각의 μ“°λ ˆλ“œλ§ˆλ‹€ μƒμ„±λ˜κ³  κ³΅μœ λ˜μ§€ μ•ŠλŠ”λ‹€.

끝

μžλ°”μ˜ 핡심 JVM의 ꡬ쑰에 λŒ€ν•΄ μ•Œμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

Reference

https://jeong-pro.tistory.com/148

https://gbsb.tistory.com/2

Written on June 13, 2021