🌱 JAVA & SPRING/Java (JVM)

Java μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ μ‹€ν–‰ κ³Όμ •κ³Ό JVM의 ꡬ쑰

ming412 2023. 8. 24. 10:46

JVMμ΄λž€?

JVM(Java Virtual Machine)μ΄λž€ μžλ°” 가상 λ¨Έμ‹ , 즉 Java ν”„λ‘œκ·Έλž¨μ„ μ‹±ν–‰ν•˜λŠ” κ°€μƒμ˜ 컴퓨터이닀.

(κ°€μƒλ¨Έμ‹ μ΄λž€ ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜κΈ° μœ„ν•œ 물리적 λ¨Έμ‹ κ³Ό μœ μ‚¬ν•œ 머신을 μ†Œν”„νŠΈμ›¨μ–΄λ‘œ κ΅¬ν˜„ν•œ 것이닀.)

 

JVM의 역할은 μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ 클래슀 λ‘œλ”λ₯Ό 톡해 읽어듀여 μ‹€ν–‰ν•˜λŠ” 것이닀.

λ˜ν•œ JVM은 Java와 OS μ‚¬μ΄μ—μ„œ μ€‘κ°œμž 역할을 μˆ˜ν–‰ν•˜μ—¬ νŠΉμ •ν•œ ν•˜λ“œμ›¨μ–΄λ‚˜ OS에 μ˜μ‘΄ν•˜μ§€ μ•Šκ³  Java μ½”λ“œλ₯Ό μ‹€ν–‰ν•  수 있게 ν•΄μ€€λ‹€. 그리고 κ°€μž₯ μ€‘μš”ν•œ, λ©”λͺ¨λ¦¬ 관리(GC)λ₯Ό μˆ˜ν–‰ν•œλ‹€.

 

μ™œ JVM을 μ•Œμ•„μ•Ό ν•˜λŠ”κ°€

ν•œμ •λœ μ‹œμŠ€ν…œ λ¦¬μ†ŒμŠ€ μ€‘μ—μ„œ κ°€μž₯ μ€‘μš”ν•œ 것은 λ©”λͺ¨λ¦¬μ΄λ‹€.

λ™μΌν•œ κΈ°λŠ₯의 ν”„λ‘œκ·Έλž¨μ΄λ”λΌλ„ λ©”λͺ¨λ¦¬ 관리에 따라 μ„±λŠ₯이 μ’Œμš°λœλ‹€. (ν”„λ‘œκ·Έλž¨μ΄ λ©”λͺ¨λ¦¬λ₯Ό 효율적으둜 μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©΄ μ„±λŠ₯ μ €ν•˜μ™€ λ©”λͺ¨λ¦¬ λΆ€μ‘± λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆλ‹€.)

 

JVM을 μ΄ν•΄ν•˜κ³  JVM이 κ΄€λ¦¬ν•˜λŠ” λ©”λͺ¨λ¦¬ ꡬ쑰λ₯Ό νŒŒμ•…ν•˜λ©΄ μžμ›μ„ μ΅œμ ν™”ν•˜μ—¬ λ©”λͺ¨λ¦¬ κ΄€λ¦¬μ˜ νš¨μœ¨μ„±μ„ 높일 수 μžˆλ‹€.

κ·Έλž˜μ„œ μ•Œμ•„λ‘λ©΄ μ’‹λ‹€λ₯Ό λ„˜μ–΄μ„œ μ•Œμ•„μ•Ό ν•˜λŠ” 것이닀.

 

Java ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ κ³Όμ •

Java ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ κ³Όμ •κ³Ό JVM의 ꡬ쑰

  1. μžλ°” ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λ˜λ©΄ JVM은 OSλ‘œλΆ€ν„° 이 ν”„λ‘œκ·Έλž¨μ΄ ν•„μš”λ‘œ ν•˜λŠ” λ©”λͺ¨λ¦¬(= Runtime Data Area)λ₯Ό ν• λ‹Ή λ°›λŠ”λ‹€. (JVM은 이 λ©”λͺ¨λ¦¬λ₯Ό μš©λ„μ— 따라 λ©”μ„œλ“œ μ˜μ—­, μŠ€νƒ μ˜μ—­, νž™ μ˜μ—­μœΌλ‘œ λ‚˜λˆ„μ–΄ κ΄€λ¦¬ν•œλ‹€.)
  2. μžλ°” 컴파일러(javac)κ°€ μ†ŒμŠ€μ½”λ“œ(.java)λ₯Ό 읽어듀여 λ°”μ΄νŠΈμ½”λ“œ(=클래슀 파일(.class))둜 λ³€ν™˜ν•œλ‹€.
  3. ν΄λž˜μŠ€λ‘œλ”(Class Loader)λ₯Ό 톡해 클래슀 νŒŒμΌλ“€μ„ JVM으둜 λ‘œλ”©ν•œλ‹€.
  4. λ‘œλ”©λœ 클래슀 νŒŒμΌμ€ μ‹€ν–‰(Execution) 엔진을 톡해 ν•΄μ„λœλ‹€.
  5. ν•΄μ„λœ λ°”μ΄νŠΈμ½”λ“œ(=클래슀 파일)λŠ” λŸ°νƒ€μž„ 데이터 μ˜μ—­μ— λ°°μΉ˜λ˜μ–΄ μ‹€μ§ˆμ μœΌλ‘œ μ‹€ν–‰λœλ‹€.
클래슀 파일: JVMμ—μ„œ 싀행될 수 μžˆλŠ” ν˜•νƒœλ‘œ μ†ŒμŠ€μ½”λ“œκ°€ 컴파일 된 ν˜•νƒœ

 

μ΄λŸ¬ν•œ κ³Όμ • μ†μ—μ„œ JVM은 ν•„μš”μ— 따라 μ“°λ ˆλ“œ λ™κΈ°ν™”λ‚˜ GC같은 관리 μž‘μ—…μ„ μˆ˜ν–‰ν•œλ‹€.

μš°μ„  JVM의 ꡬ쑰에 λŒ€ν•΄ μ‚΄νŽ΄λ³΄μž.

 

JVM의 ꡬ쑰

JVM은 ν΄λž˜μŠ€λ‘œλ”, μ‹€ν–‰ μ—”μ§„, λŸ°νƒ€μž„ 데이터 μ˜μ—­μœΌλ‘œ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€.

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

μžλ°” 컴파일러(javac)에 μ˜ν•΄ λ³€ν™˜λœ 클래슀(.class) νŒŒμΌμ„ JVM λ‚΄λ‘œ λ‘œλ“œν•˜λŠ” λͺ¨λ“ˆμ΄λ‹€. (λŸ°νƒ€μž„ μ‹œμ— λ™μ μœΌλ‘œ 클래슀 νŒŒμΌμ„ λ‘œλ“œν•œλ‹€.)

클래슀 λ‘œλ”μ— λŒ€ν•΄μ„œλŠ” 이 κΈ€μ—μ„œ μžμ„Ένžˆ μ„€λͺ…ν•œλ‹€.

컴파일 νƒ€μž„: μ†ŒμŠ€μ½”λ“œκ°€ κΈ°κ³„μ–΄λ‘œ λ³€ν™˜λ˜μ–΄ μ‹€ν–‰κ°€λŠ₯ν•œ ν”„λ‘œκ·Έλž¨μ΄ λ˜λŠ” κ³Όμ •
λŸ°νƒ€μž„: 컴파일 νƒ€μž„ 이후 ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λ˜λŠ” λ•Œ (= λ°”μ΄νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ν•  λ•Œ)

 

클래슀 λ‘œλ” λ‘œλ”© κ³Όμ •

컴파일된 클래슀 νŒŒμΌμ€ λ‘œλ”©(Loading), 링킹(Linking), μ΄ˆκΈ°ν™”(Initialization)의 단계λ₯Ό 거쳐 JVMμ—μ„œ μ‚¬μš©ν•  수 있게 λœλ‹€.

1-1. Loading (λ‘œλ”©)

μš°μ„  클래슀 λ‘œλ”λŠ” μžλ°” λ°”μ΄νŠΈ μ½”λ“œ(.class)λ₯Ό 읽고, κ·Έ λ‚΄μš©μ— 따라 μ μ ˆν•œ λ°”μ΄λ„ˆλ¦¬ 데이터λ₯Ό λ§Œλ“€κ³  λ©”μ„œλ“œ μ˜μ—­μ— μ €μž₯ν•œλ‹€.

이 κ³Όμ •μ—μ„œ .class 파일이 JVM μŠ€νŽ™μ— λ§žλŠ”μ§€ ν™•μΈν•˜κ³ , Java Version을 ν™•μΈν•œλ‹€.

1-2. Linking (링킹)

Verifying(검증): 읽어 듀인 클래슀 파일이 μœ νš¨ν•œ 것인지 ν™•μΈν•œλ‹€. 클래슀 파일 ν˜•μ‹μ΄ μœ νš¨ν•œμ§€(= μžλ°” μ–Έμ–΄ λͺ…μ„Έ & JVM λͺ…세에 λͺ…μ‹œλœ λŒ€λ‘œ 잘 κ΅¬μ„±λ˜μ–΄ μžˆλŠ”μ§€) κ²€μ¦ν•œλ‹€. 

Preparing(μ€€λΉ„): ν΄λž˜μŠ€κ°€ ν•„μš”λ‘œ ν•˜λŠ” λ©”λͺ¨λ¦¬ 곡간을 ν• λ‹Ήν•œλ‹€. ν΄λž˜μŠ€μ— μ •μ˜λœ ν•„λ“œ, λ©”μ„œλ“œ, μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 데이터 ꡬ쑰λ₯Ό μ€€λΉ„ν•œλ‹€.

Resolving(뢄석): μ„ νƒμ μœΌλ‘œ μ§„ν–‰λ˜λŠ” κ³Όμ •μœΌλ‘œ μ‚¬μš©ν•˜λŠ” ν™˜κ²½μ— 따라 λ™μž‘ μœ λ¬΄κ°€ μ •ν•΄μ§„λ‹€. 심볼릭 λ©”λͺ¨λ¦¬ 레퍼런슀λ₯Ό λ©”μ„œλ“œ μ˜μ—­μ— μžˆλŠ” μ‹€μ œ 레퍼런슀둜 κ΅μ²΄ν•œλ‹€.

1-3. Initialization (μ΄ˆκΈ°ν™”)

링킹 λ‹¨κ³„μ˜ Prepare λ‹¨κ³„μ—μ„œ ν™•λ³΄ν•œ λ©”λͺ¨λ¦¬ μ˜μ—­μ— 클래슀의 static 값듀을 ν• λ‹Ήν•œλ‹€.

 

2) Execution (μ‹€ν–‰ μ—”μ§„)

클래슀(=λ°”μ΄νŠΈ μ½”λ“œ)λ₯Ό μ‹€ν–‰μ‹œν‚€λŠ” 역할을 ν•œλ‹€.

ν΄λž˜μŠ€λ‘œλ”κ°€ JVM λ‚΄μ˜ λŸ°νƒ€μž„ 데이터 μ˜μ—­μ— λ°”μ΄νŠΈ μ½”λ“œλ₯Ό λ°°μΉ˜μ‹œν‚€κ³ , 이것은 μ‹€ν–‰ 엔진에 μ˜ν•΄ μ‹€ν–‰λœλ‹€.

 

μžλ°” λ°”μ΄νŠΈ μ½”λ“œλŠ” 기계가 λ°”λ‘œ μˆ˜ν–‰ν•  수 μžˆλŠ” μ–Έμ–΄λ³΄λ‹€λŠ” 비ꡐ적 인간이 보기 νŽΈν•œ ν˜•νƒœλ‘œ 기술된 것이닀.

λ”°λΌμ„œ μ‹€ν–‰ 엔진은 이와 같은 λ°”μ΄νŠΈ μ½”λ“œλ₯Ό μ‹€μ œλ‘œ JVM λ‚΄λΆ€μ—μ„œ 기계가 μ‹€ν–‰ν•  수 μžˆλŠ” ν˜•νƒœλ‘œ λ³€κ²½ν•˜λŠ”λ°, 이 λ•Œ 인터프리터 방식 λ˜λŠ” JIT 방식을 μ‚¬μš©ν•œλ‹€.

2-1. Interpreter (인터프리터)

μ‹€ν–‰ 엔진은 μžλ°” λ°”μ΄νŠΈ μ½”λ“œλ₯Ό λͺ…λ Ήμ–΄ λ‹¨μœ„λ‘œ μ½μ–΄μ„œ μ‹€ν–‰ν•œλ‹€.

ν•˜μ§€λ§Œ 이 방식은 인터프리터 μ–Έμ–΄μ˜ 단점을 κ·ΈλŒ€λ‘œ κ°€μ§€κ³  μžˆλ‹€. ν•œ 쀄씩 μˆ˜ν–‰ν•˜κΈ° λ•Œλ¬Έμ— λŠλ¦¬λ‹€λŠ” 것이닀.

2-2. JIT(Just-In-Time) Compiler

인터프리터 λ°©μ‹μ˜ 단점을 λ³΄μ™„ν•˜κΈ° μœ„ν•΄ λ„μž…λœ μ»΄νŒŒμΌλŸ¬μ΄λ‹€. μ΅œκ·Όμ— JIT 컴파일 λ°©μ‹μœΌλ‘œ μžλ°” 컴파일러λ₯Ό κ°œμ„ ν•˜μ—¬ Java ν”„λ‘œκ·Έλž¨ μ‹€ν–‰ 속도가 많이 λΉ¨λΌμ‘Œλ‹€.

 

인터프리터 λ°©μ‹μœΌλ‘œ μ‹€ν–‰ν•˜λ‹€κ°€ μ μ ˆν•œ μ‹œμ μ— λ°”μ΄νŠΈ μ½”λ“œ 전체λ₯Ό μ»΄νŒŒμΌν•˜μ—¬ λ„€μ΄ν‹°λΈŒ μ½”λ“œλ‘œ λ³€κ²½ν•˜κ³ , μ΄ν›„μ—λŠ” 더이상 μΈν„°ν”„λ¦¬νŒ… ν•˜μ§€ μ•Šκ³  λ„€μ΄ν‹°λΈŒ μ½”λ“œλ‘œ 직접 μ‹€ν–‰ν•˜λŠ” 방식이닀.

λ„€μ΄ν‹°λΈŒ μ½”λ“œλŠ” μΊμ‹œμ— λ³΄κ΄€ν•˜κΈ° λ•Œλ¬Έμ— ν•œ 번 컴파일 된 μ½”λ“œλŠ” λΉ λ₯΄κ²Œ μˆ˜ν–‰ν•˜κ²Œ λœλ‹€.

 

λ‹€λ§Œ, JIT μ»΄νŒŒμΌλŸ¬κ°€ 컴파일 ν•˜λŠ” 과정이 λ°”μ΄νŠΈ μ½”λ“œλ₯Ό μΈν„°ν”„λ¦¬νŒ… ν•˜λŠ” 과정보닀 훨씬 였래 κ±Έλ¦¬λ―€λ‘œ, ν•œ 번만 μ‹€ν–‰λ˜λŠ” μ½”λ“œλΌλ©΄ 컴파일 ν•˜μ§€ μ•Šκ³  μΈν„°ν”„λ¦¬νŒ… ν•˜λŠ” 것이 μœ λ¦¬ν•˜λ‹€.

λ”°λΌμ„œ JIT 컴파일러λ₯Ό μ‚¬μš©ν•˜λŠ” JVM듀은 λ‚΄λΆ€μ μœΌλ‘œ ν•΄λ‹Ή λ©”μ„œλ“œκ°€ μ–Όλ§ˆλ‚˜ 자주 μˆ˜ν–‰λ˜λŠ”μ§€ μ²΄ν¬ν•˜κ³ , 일정 정도λ₯Ό λ„˜μ„ λ•Œμ—λ§Œ μ»΄νŒŒμΌμ„ μˆ˜ν–‰ν•œλ‹€. 

2-3. GC (Garbage Collector)

JVM의 λ©”λͺ¨λ¦¬ 관리 기법 쀑 ν•˜λ‚˜λ‘œ νž™ μ˜μ—­μ—μ„œ λΆˆν•„μš”ν•œ λ©”λͺ¨λ¦¬λ₯Ό ν•΄μ œν•˜μ—¬ μ‹œμŠ€ν…œμ˜ κ°€μš© λ©”λͺ¨λ¦¬λ₯Ό μœ μ§€ν•˜κ³  λ©”λͺ¨λ¦¬ λˆ„μˆ˜λ₯Ό λ°©μ§€ν•œλ‹€.

κ°€λΉ„μ§€ μ»¬λ ‰μ…˜μ— λŒ€ν•΄μ„œλŠ” 이 κΈ€μ—μ„œ μžμ„Ένžˆ μ„€λͺ…ν•œλ‹€.

 

3) Runtime Data Area

λŸ°νƒ€μž„ 데이터 μ˜μ—­ (=λ©”λͺ¨λ¦¬ μ˜μ—­)

μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ‹€ν–‰λ˜λ©΄ JVM은 OS둜 λΆ€ν„° λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ή λ°›λŠ”λ°, 이 λ©”λͺ¨λ¦¬ 곡간을 λŸ°νƒ€μž„ 데이터 μ˜μ—­μ΄λΌκ³  ν•œλ‹€.

JVM은 이 λ©”λͺ¨λ¦¬λ₯Ό μš©λ„μ— 따라 λ©”μ„œλ“œ μ˜μ—­, μŠ€νƒ μ˜μ—­, νž™ μ˜μ—­μœΌλ‘œ λ‚˜λˆ„μ–΄ κ΄€λ¦¬ν•œλ‹€.

 

3-1. λ©”μ„œλ“œ μ˜μ—­

λ©”μ„œλ“œ μ˜μ—­μ€ ν”„λ‘œκ·Έλž¨μ˜ μ‹€ν–‰ μ½”λ“œμ™€ static λ³€μˆ˜λ₯Ό μ €μž₯ν•œλ‹€.

 

μŠ€ν”„λ§ λΆ€νŠΈ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 경우, Java λ°”μ΄νŠΈ μ½”λ“œκ°€ 이 μ˜μ—­μ— μœ„μΉ˜ν•œλ‹€. 컨트둀러, μ„œλΉ„μŠ€, λ ˆν¬μ§€ν† λ¦¬μ™€ 같은 클래슀의 λ©”μ„œλ“œλ“€, Java ν‘œμ€€ 라이브러리의 ν•¨μˆ˜λ“€, μŠ€ν”„λ§ ν”„λ ˆμž„μ›Œν¬ μ½”λ“œ 등이 ν¬ν•¨λœλ‹€.

 

Javaμ—μ„œλŠ” static ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ •μ˜λœ λ³€μˆ˜λ‚˜ 객체 등이 이 μ˜μ—­μ— ν• λ‹Ήλœλ‹€.

예λ₯Ό λ“€μ–΄, μŠ€ν”„λ§ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ Singleton Scope의 Beanμ΄λ‚˜ μ •μ μœΌλ‘œ μ„ μ–Έλœ μ„€μ • 값듀이 이 μ˜μ—­μ— μœ„μΉ˜ν•  수 μžˆλ‹€.

 

λ©”μ„œλ“œ μ˜μ—­μ€ JVM이 λ™μž‘ν•΄μ„œ ν΄λž˜μŠ€κ°€ λ‘œλ”©λ  λ•Œ ν• λ‹Ήλ˜λ©°,

ν”„λ‘œκ·Έλž¨ μ‹œμž‘ 전에 λ‘œλ“œλ˜μ–΄ μ’…λ£ŒκΉŒμ§€ λ©”λͺ¨λ¦¬μ— λ‚¨μ•„μžˆλ‹€.

3-2. μŠ€νƒ μ˜μ—­

μŠ€νƒ μ˜μ—­μ€ λ©”μ„œλ“œμ˜ μ§€μ—­λ³€μˆ˜μ™€ λ§€κ°œλ³€μˆ˜λ₯Ό ν”„λ ˆμž„(frame) ν˜•νƒœλ‘œ μ €μž₯ν•œλ‹€.

예λ₯Ό λ“€μ–΄, HTTP μš”μ²­μ΄ λ“€μ–΄μ˜€λ©΄ ν•΄λ‹Ή μš”μ²­μ„ μ²˜λ¦¬ν•˜λŠ” 컨트둀러 λ©”μ„œλ“œκ°€ 호좜될 λ•Œ, ν•΄λ‹Ή λ©”μ„œλ“œμ˜ λ§€κ°œλ³€μˆ˜, μ§€μ—­λ³€μˆ˜, 리턴 μ£Όμ†Œ 등이 μŠ€νƒμ— push λœλ‹€. 이후 λ©”μ„œλ“œ 싀행이 μ™„λ£Œλ˜λ©΄ ν•΄λ‹Ή μ •λ³΄λŠ” μŠ€νƒμ—μ„œ pop λ˜μ–΄ μ œκ±°λœλ‹€.

 

μŠ€νƒ μ˜μ—­μ€ 컴파일 νƒ€μž„μ— ν• λ‹Ήλœλ‹€.

3-3. νž™ μ˜μ—­

νž™ μ˜μ—­μ€ λ™μ μœΌλ‘œ μƒμ„±λœ 객체듀을 μ €μž₯ν•œλ‹€.

μŠ€ν”„λ§ λΆ€νŠΈ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ new ν‚€μ›Œλ“œλ‘œ μƒμ„±λœ κ°μ²΄λ‚˜ λ°°μ—΄, Sprign Bean, JPA μ—”ν‹°ν‹° 객체 λ“± λ‹€μ–‘ν•œ 객체듀이 이 μ˜μ—­μ— ν• λ‹Ήλœλ‹€. GC(κ°€λΉ„μ§€ 컬렉터)의 관리 λŒ€μƒμ΄κΈ° λ•Œλ¬Έμ—, 더이상 μ°Έμ‘°λ˜μ§€ μ•ŠλŠ” 객체의 λ©”λͺ¨λ¦¬ μ˜μ—­μ€ GC에 μ˜ν•΄ νšŒμˆ˜λœλ‹€.

 

νž™ μ˜μ—­μ€ λŸ°νƒ€μž„μ— ν• λ‹Ήλœλ‹€.

 

νž™ μ˜μ—­μ€ GC의 관리 λŒ€μƒμ΄λΌκ³  ν–ˆλ‹€.

κ·Έλ ‡λ‹€λ©΄ νž™ μ˜μ—­μ΄ μ–΄λ–»κ²Œ κ΅¬μ„±λ˜μ–΄ 있고 GCλŠ” 이λ₯Ό μ–΄λ–»κ²Œ κ΄€λ¦¬ν•˜λŠ”μ§€ κΆκΈˆν•˜λ‹€λ©΄ 이 글을 μ°Έκ³ ν•˜μž.

 

참고 자료

μžλ°”κ°€μƒλ¨Έμ‹ , JVMμ΄λž€ 무엇인가?

μžλ°” μ½”λ“œμ™€ λ©”μ„œλ“œ, μŠ€νƒœν‹± λ³€μˆ˜ 등은 λ©”λͺ¨λ¦¬μ˜ 어디에 μœ„μΉ˜ν• κΉŒ?

[Java] Java 8 vs Java 11

[Java] μžλ°” ν΄λž˜μŠ€λ‘œλ”(Class Loader)

[java] μžλ°” λ©”λͺ¨λ¦¬ ꡬ쑰(static, stack, heap)