[Java] πŸ€– JVMμ΄λž€?

Sangho HanΒ·2025λ…„ 5μ›” 29일
2

β˜•οΈΒ Java

λͺ©λ‘ 보기
16/17
post-thumbnail

πŸ€– JVMμ΄λž€?

JVM(Java Virtual Machine)은 μžλ°” ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜κΈ° μœ„ν•œ 가상 컴퓨터(μΆ”μƒν™”λœ 기계)이닀.

WORA?

μžλ°”μ—λŠ” WORAλΌλŠ” μ€‘μš”ν•œ νŠΉμ§•μ΄ μ‘΄μž¬ν•œλ‹€.
μ΄λŠ” "Write Once Run Anywhere" 의 μ€€λ§λ‘œ, ν•œ 번 μž‘μ„±λœ μ½”λ“œλŠ” μ–΄λ””μ—μ„œλ“  μ‚¬μš© κ°€λŠ₯ν•˜λ‹€λŠ” λœ»μ΄λ‹€.

즉, ν•œ 번 μ»΄νŒŒμΌμ„ ν•΄ 두면 μ–΄λ–€ OS μœ„μ—μ„œλ„ μ‚¬μš©ν•  수 μžˆλ‹€λŠ” 것이며, 이λ₯Ό OS 쒅속적이지 μ•Šλ‹€κ³ λ„ λΆ€λ₯Ό 수 μžˆλ‹€.

ν•΄λ‹Ή νŠΉμ§•μ€ 기쑴의 μ–΄μ…ˆλΈ”λ¦¬μ–΄, Cμ–Έμ–΄μ˜ 단점을 λ³΄μ™„ν•΄μ£Όμ—ˆκ³ , 이둜 인해 λ§Žμ€ μ‚¬λžŒλ“€μ΄ μžλ°”λ₯Ό μ• μš©ν•˜κ²Œ λ˜μ—ˆλ‹€.

그리고 이λ₯Ό κ°€λŠ₯ν•˜κ²Œ ν•΄ μ£ΌλŠ” 것이 λ°”λ‘œ JVM의 역할이닀.

컴파일

JavaλŠ” *.java, Python은 *.py와 같은 μ›μ‹œμ½”λ“œλ₯Ό λ§Œλ“€κ²Œ λœλ‹€.

μ΄λŠ” 인간이 읽을 수 μžˆλŠ” κ³ μˆ˜μ€€ μ–Έμ–΄λ‘œ, CPUκ°€ 읽게 ν•˜κΈ° μœ„ν•΄μ„œλŠ” κΈ°κ³„μ–΄λ‘œ μ»΄νŒŒμΌμ„ ν•΄ μ£ΌλŠ” 과정이 ν•„μš”ν•˜λ‹€.

μ—¬κΈ°μ„œ μžλ°”λŠ” JVM을 κ±°μ³μ„œ OS둜 λ„λ‹¬ν•˜κΈ° λ•Œλ¬Έμ— λ°”λ‘œ κΈ°κ³„μ–΄λ‘œ 컴파일 ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, JVM이 인식할 수 μžˆλŠ” Java Bytecode둜 λ³€ν™˜λœλ‹€.

Java Bytecode

μžλ°” λ°”μ΄νŠΈμ½”λ“œλŠ”, JVM의 λͺ…λ Ήμ–΄ 집합이닀. ν•΄λ‹Ή λ°”μ΄νŠΈμ½”λ“œμ™€ JVM의 λ™μž‘μ€ μΌκ΄€λ˜κΈ° λ•Œλ¬Έμ—, OS의 ꡬ뢄 없이 μ‹€ν–‰ν•  수 있게 λœλ‹€.

μ—¬κΈ°μ„œ λ°”μ΄νŠΈμ½”λ“œλŠ” 각 λͺ…λ Ήμ–΄κ°€ 1λ°”μ΄νŠΈ λ‹¨μœ„λ‘œ κ΅¬μ„±λ˜μ–΄ 있기 λ•Œλ¬Έμ— 이런 이름이 λΆ™μ—ˆλ‹€.

Java Compiler

λ°”μ΄νŠΈμ½”λ“œλ₯Ό λ§Œλ“€μ–΄ μ£ΌλŠ” 역할은 λˆ„κ°€ ν• κΉŒ?

μ΄λŠ” Java Compilerκ°€ 맑으며, JDKλ₯Ό μ„€μΉ˜ν•˜λ©΄ bin 내에 μ‘΄μž¬ν•˜λŠ” javac.exeλ₯Ό λ§ν•œλ‹€.

test.javaλΌλŠ” 파일이 μ‘΄μž¬ν•œλ‹€κ³  κ°€μ •ν•΄ 보자.
μ•„λž˜ λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•˜λ©΄, .java(μ›μ‹œ μ½”λ“œ) -> .class(λ°”μ΄νŠΈμ½”λ“œ)둜 λ³€ν™˜ν•  수 μžˆλ‹€.

javac test.java

그럼 λ™μΌν•œ 디렉토리 내에 λ°”μ΄νŠΈμ½”λ“œ .class 파일이 μƒκΈ°κ²Œ λœλ‹€.

JIT 컴파일러

λ°”μ΄νŠΈμ½”λ“œλŠ” JVM이 읽을 수 μžˆλŠ” λͺ…령어이닀.
JVM은 이λ₯Ό 읽고 컴퓨터가 인식할 수 μžˆλŠ” λ°”μ΄λ„ˆλ¦¬ μ½”λ“œλ‘œ λ³€ν™˜ν•˜κ²Œ λœλ‹€.

λ°”μ΄λ„ˆλ¦¬ μ½”λ“œ

이진 μ½”λ“œλΌκ³ λ„ λΆ€λ₯΄λ©°, 0κ³Ό 1둜만 κ΅¬μ„±λ˜μ–΄ μžˆλ‹€.
CPUκ°€ μ΄ν•΄ν•˜λŠ” λͺ…λ Ήμ–΄ 집합인 κΈ°κ³„μ–΄λŠ” ν•΄λ‹Ή 이진 μ½”λ“œλ‘œ 이루어진닀.

μ—¬κΈ°μ„œ λ°”μ΄νŠΈμ½”λ“œ -> λ°”μ΄λ„ˆλ¦¬ μ½”λ“œλ‘œ λ³€ν™˜ν•΄ μ£ΌλŠ” 것이 JIT μ»΄νŒŒμΌλŸ¬μ΄λ‹€.

JIT μ»΄νŒŒμΌλŸ¬λŠ” 동적 λ²ˆμ—­μ„ ν•œλ‹€κ³ λ„ λ§ν•˜λŠ”λ°, ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜λ©° μ‹€μ‹œκ°„μœΌλ‘œ κΈ°κ³„μ–΄λ‘œ λ²ˆμ—­ν•˜λŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€.

그렇기에 Just-In-Time(JIT) 컴파일러인 것이닀.

JIT μ»΄νŒŒμΌλŸ¬κ°€ 생긴 이유

JIT μ»΄νŒŒμΌλŸ¬λŠ” μ²˜μŒλΆ€ν„° 있던 μš”μ†ŒλŠ” μ•„λ‹ˆλ‹€.

μžλ°”λŠ” WORAλΌλŠ” μž₯점이 μ‘΄μž¬ν•˜μ§€λ§Œ, 이λ₯Ό μœ„ν•΄μ„œλŠ” μ•„λž˜μ˜ 과정이 ν•„μš”ν–ˆλ‹€.

  1. μ›μ‹œμ½”λ“œλ₯Ό μžλ°” μ»΄νŒŒμΌλŸ¬κ°€ λ°”μ΄νŠΈμ½”λ“œλ‘œ μ»΄νŒŒμΌν•œλ‹€.
  2. λ°”μ΄νŠΈμ½”λ“œλ₯Ό JVM이 ν•œ 쀄씩, 즉 인터프리터 λ°©μ‹μœΌλ‘œ μ½μ–΄μ„œ μ‹€ν–‰ν•œλ‹€.

그렇기에 λ‹€λ₯Έ 언어에 λΉ„ν•΄μ„œ μ„±λŠ₯이 λŠλ¦¬λ‹€λŠ” 단점이 μ‘΄μž¬ν–ˆκ³ , 이λ₯Ό κ°œμ„ ν•˜κΈ° μœ„ν•΄μ„œ νƒ„μƒν•œ 것이 JIT μ»΄νŒŒμΌλŸ¬μ΄λ‹€.

μ΄λŸ¬ν•œ νŠΉμ§• λ•Œλ¬Έμ— μžλ°”λŠ” 컴파일 μ–Έμ–΄κ°€ μ•„λ‹Œ ν•˜μ΄λΈŒλ¦¬λ“œ 언어라 λΆ€λ₯΄λŠ” 것이 맞으며, 이에 λŒ€ν•΄μ„œλŠ” κΈ€λ‘œ μ •λ¦¬ν•΄λ‘μ—ˆλ‹€.


πŸ› οΈ JVM의 ꡬ성 μš”μ†Œ

JVM은 μ•„λž˜μ™€ 같이 κ΅¬μ„±λ˜μ–΄ μžˆλ‹€.

  1. 클래슀 λ‘œλ”(Class Loader)
  2. μ‹€ν–‰ μ—”μ§„(Execution Engine)
    2-1. 인터프리터(Interpreter)
    2-2. JIT 컴파일러(Just-In-Time Compiler)
    2-3. κ°€λΉ„μ§€ μ½œλ ‰ν„°(Garbage Collector)
  3. λŸ°νƒ€μž„ 데이터 μ˜μ—­(Runtime Data Area)

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

이미지 좜처 및 μžμ„Έν•œ μ„€λͺ… κΈ€

클래슀 λ‘œλ”λŠ” 이름 κ·ΈλŒ€λ‘œ, JVM 내에 .class νŒŒμΌμ„ λ‘œλ“œν•˜κ³  링크λ₯Ό 톡해 λ°°μΉ˜ν•˜λŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” λͺ¨λ“ˆμ΄λ‹€.

μžλ°”λŠ” 컴파일 νƒ€μž„μ΄ μ•„λ‹Œ, λŸ°νƒ€μž„ μ‹œμ μ— 클래슀 λ‘œλ”© 및 링크가 μ΄λ£¨μ–΄μ§€λŠ” 동적 λ‘œλ”©(Dynamic Loading) 방식을 λ”°λ₯Έλ‹€.

μ—¬κΈ°μ„œ JVM의 λ©”μ†Œλ“œ μ˜μ—­μ— λ™μ μœΌλ‘œ 클래슀 λ‘œλ“œλ₯Ό λ‹΄λ‹Ήν•˜λŠ” 뢀뢄이 클래슀 λ‘œλ”μ΄λ‹€.

클래슀 λ‘œλ” 3단계

클래슀 λ‘œλ”λŠ” 3λ‹¨κ³„λ‘œ λ‚˜λ‰˜μ–΄μ Έ μžˆλ‹€.

λ‘œλ”©

  • λ°”μ΄νŠΈμ½”λ“œ(.class)λ₯Ό λ©”μ†Œλ“œ μ˜μ—­μ— μ €μž₯ν•œλ‹€.
  • 각 λ°”μ΄νŠΈμ½”λ“œλŠ” JVM에 μ˜ν•΄μ„œ λ©”μ†Œλ“œ μ˜μ—­μ— λ‹€μŒ 정보듀을 μ €μž₯ν•œλ‹€.
    1) λ‘œλ“œλœ 클래슀 + 그의 λΆ€λͺ¨ 클래슀의 정보
    2) 클래슀 파일과 Class, Interface, Enum의 κ΄€λ ¨ μ—¬λΆ€
    3) λ³€μˆ˜ & λ©”μ†Œλ“œ λ“± 정보

링크
1) 검증 : 읽은 클래슀(λ°”μ΄νŠΈμ½”λ“œ)κ°€ μžλ°” μ–Έμ–΄ λͺ…μ„Έ 및 JVM λͺ…세에 λͺ…μ‹œλœλŒ€λ‘œ 잘 κ΅¬μ„±λ˜μ–΄ μžˆλŠ”μ§€ κ²€μ‚¬ν•œλ‹€.
2) μ€€λΉ„ : ν΄λž˜μŠ€κ°€ ν•„μš”λ‘œ ν•˜λŠ” λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•˜κ³ , ν΄λž˜μŠ€μ—μ„œ μ •μ˜λœ ν•„λ“œ & λ©”μ†Œλ“œ & μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ‚˜νƒ€λ‚΄λŠ” 데이터 ꡬ쑰λ₯Ό μ€€λΉ„ν•œλ‹€.
3) 뢄석 : 심볼릭 λ©”λͺ¨λ¦¬ 레퍼런슀λ₯Ό λ©”μ†Œλ“œ μ˜μ—­μ— μžˆλŠ” μ‹€μ œ 레퍼런슀둜 κ΅μ²΄ν•œλ‹€.

  • μ—¬κΈ°μ„œ 검증은 JVM λ‚΄λΆ€μ˜ λ°”μ΄νŠΈμ½”λ“œ 검증기(Verifier)κ°€ μˆ˜ν–‰ν•˜λ©°, Java Language Specification (JLS, μžλ°” λͺ…μ„Έ) & Java Virtual Machine Specification (JVMS, JVM λͺ…μ„Έ)λ₯Ό μ°Έμ‘°ν•œλ‹€.

μ΄ˆκΈ°ν™”

  • 클래슀 λ³€μˆ˜λ“€μ„ μ μ ˆν•œ κ°’μœΌλ‘œ μ΄ˆκΈ°ν™”, 즉 static ν•„λ“œλ“€μ΄ μ„€μ •λœ κ°’μœΌλ‘œ μ΄ˆκΈ°ν™”λœλ‹€.

μ΄ˆκΈ°ν™” λ‹¨κ³„μ—μ„œ static ν•„λ“œλ§Œ μ΄ˆκΈ°ν™”ν•˜λŠ” 이유?

클래슀 μ΄ˆκΈ°ν™” λ‹¨κ³„μ—μ„œλŠ” static ν•„λ“œμ— λŒ€ν•΄μ„œλ§Œ μ΄ˆκΈ°ν™”λ₯Ό μˆ˜ν–‰ν•œλ‹€.

μ™œλƒν•˜λ©΄ static ν•„λ“œλŠ” 클래슀 λ‹¨μœ„λ‘œ κ΄€λ¦¬λ˜λ©°, λͺ¨λ“  μΈμŠ€ν„΄μŠ€κ°€ κ³΅μœ ν•˜λŠ” 전역적인 μžμ›μ΄κΈ° λ•Œλ¬Έμ΄λ‹€.

λ˜ν•œ ν•΄λ‹Ή μžμ›μ€ μΈμŠ€ν„΄μŠ€ 생성 여뢀와 λ¬΄κ΄€ν•˜κ²Œ μ‚¬μš©λ  수 있기 λ•Œλ¬Έμ—, JVM은 ν΄λž˜μŠ€κ°€ 처음 λ‘œλ”©λ  λ•Œ ν•œ 번만 μ΄ˆκΈ°ν™”λ₯Ό μˆ˜ν–‰ν•˜κ³ , μ΄ν›„μ—λŠ” ν•΄λ‹Ή ν•„λ“œλ₯Ό λ©”λͺ¨λ¦¬μ— 올렀 두고 μž¬μ‚¬μš©ν•œλ‹€.

반면, non-static ν•„λ“œλŠ” 각 μΈμŠ€ν„΄μŠ€λ§ˆλ‹€ λ…λ¦½μ μœΌλ‘œ μ‘΄μž¬ν•˜λ©°, μΈμŠ€ν„΄μŠ€κ°€ 생성될 λ•Œλ§ˆλ‹€ λ³„λ„λ‘œ μ΄ˆκΈ°ν™”λ˜λ―€λ‘œ 클래슀 μ΄ˆκΈ°ν™” λ‹¨κ³„μ—μ„œλŠ” 처리 λŒ€μƒμ΄ μ•„λ‹ˆκ²Œ λœλ‹€.

즉, 클래슀 μ΄ˆκΈ°ν™”λŠ” 전역적인 μžμ›μ˜ 일관성과 효율적인 관리λ₯Ό μœ„ν•΄ static ν•„λ“œμ™€ static λΈ”λ‘λ§Œμ„ λŒ€μƒμœΌλ‘œ μˆ˜ν–‰λœλ‹€.

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

μ‹€μ§ˆμ μœΌλ‘œ λ°”μ΄νŠΈμ½”λ“œλ₯Ό μ‹€ν–‰μ‹œν‚€λŠ” 곳이닀.

클래슀 λ‘œλ”κ°€ JVM λŸ°νƒ€μž„ 데이터 μ˜μ—­ 내에 λ°”μ΄νŠΈμ½”λ“œλ₯Ό λ°°μΉ˜μ‹œν‚€κ²Œ 되고, 이λ₯Ό μ‹€ν–‰ 엔진이 μ‹€ν–‰ν•œλ‹€.

μ—¬κΈ°μ—λŠ” μ•„λž˜ 3κ°€μ§€ κ΅¬μ„±μš”μ†Œκ°€ μ‘΄μž¬ν•œλ‹€.

  1. 인터프리터
  2. JIT 컴파일러
  3. GC(Garbage Collector)

1, 2λ²ˆμ€ μœ„ JIT μ»΄νŒŒμΌλŸ¬κ°€ 생긴 μ΄μœ μ—μ„œ μ„€λͺ…ν–ˆμœΌλ‹ˆ λ„˜μ–΄κ°€κ³ , 3번 GC에 λŒ€ν•΄μ„œλ§Œ κ°„λ‹¨νžˆ μ„€λͺ…ν•˜κ³ μž ν•œλ‹€.

GC(Garbage Collector)

κ°€λΉ„μ§€ μ»¬λ ‰ν„°λŠ” JVM이 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 객체(더 이상 μ°Έμ‘°λ˜μ§€ μ•ŠλŠ” 객체)λ₯Ό μžλ™μœΌλ‘œ νƒμ§€ν•˜κ³  νž™ λ©”λͺ¨λ¦¬μ—μ„œ μ œκ±°ν•΄μ£ΌλŠ” κΈ°λŠ₯이닀.

κ°œλ°œμžκ°€ 직접 λ©”λͺ¨λ¦¬λ₯Ό ν•΄μ œν•˜μ§€ μ•Šμ•„λ„ λ˜λ―€λ‘œ λ©”λͺ¨λ¦¬ λˆ„μˆ˜λ₯Ό λ°©μ§€ν•˜κ³  μžλ°”μ˜ μ•ˆμ „μ„±μ„ λ†’μ—¬μ£ΌλŠ” 역할을 ν•œλ‹€.

GC에 λŒ€ν•΄μ„œλŠ” ν•΄λ‹Ή κΈ€λ‘œ μ •λ¦¬ν•΄λ‘μ—ˆλ‹€.

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

λŸ°νƒ€μž„ 데이터 μ˜μ—­μ€ JVM이 μžλ°” ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•  λ•Œ μ‚¬μš©ν•˜λŠ” λ©”λͺ¨λ¦¬ κ³΅κ°„μ˜ ꡬ쑰λ₯Ό λœ»ν•œλ‹€.

μ΄λŠ” 클래슀 정보, 객체, λ³€μˆ˜, μŠ€λ ˆλ“œ μ‹€ν–‰ 정보 등을 μ €μž₯ν•˜λŠ” μ—¬λŸ¬ μ˜μ—­μœΌλ‘œ λ‚˜λ‰œλ‹€.

PC Register

각 μŠ€λ ˆλ“œλ§ˆλ‹€ 1κ°œμ”© μ‘΄μž¬ν•˜λŠ” μž‘μ€ λ©”λͺ¨λ¦¬ κ³΅κ°„μœΌλ‘œ, μŠ€λ ˆλ“œκ°€ μƒˆλ‘œ 생성될 λ•Œ ν•¨κ»˜ μƒμ„±λœλ‹€.

ν˜„μž¬ μ‹€ν–‰ 쀑인 μžλ°” λ°”μ΄νŠΈμ½”λ“œ λͺ…λ Ήμ–΄μ˜ μ£Όμ†Œλ₯Ό μ €μž₯ν•˜λ©°, JVM이 μ–΄λ–€ λͺ…λ Ήμ–΄λ₯Ό λ‹€μŒμ— μ‹€ν–‰ν• μ§€λ₯Ό κ²°μ •ν•˜λŠ” 데 μ‚¬μš©λœλ‹€.

μŠ€λ ˆλ“œλ§ˆλ‹€ λ…λ¦½μ μ΄λ―€λ‘œ, μŠ€λ ˆλ“œ κ°„ κ°„μ„­ 없이 λͺ…λ Ήμ–΄ μ‹€ν–‰ 흐름을 좔적할 수 μžˆλ‹€.

JVM Stack

ν”„λ‘œκ·Έλž¨ μ‹€ν–‰κ³Όμ •μ—μ„œ μž„μ‹œλ‘œ ν• λ‹Ήλ˜μ—ˆλ‹€κ°€, λ©”μ„œλ“œλ₯Ό λΉ μ Έλ‚˜κ°€λ©΄ μ†Œλ©Έλ˜λŠ” νŠΉμ„±μ˜ 데이터λ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•œ μ˜μ—­μ΄λ‹€.

λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œλ§ˆλ‹€, ν•΄λ‹Ή μ˜μ—­μ— κ³ μœ ν•œ μŠ€νƒ ν”„λ ˆμž„μ΄ μƒμ„±λœλ‹€. λ©”μ„œλ“œ μˆ˜ν–‰μ΄ μ™„λ£Œλ˜λ©΄ ν”„λ ˆμž„μ΄ μ œκ±°λœλ‹€.

이 μ˜μ—­μ—λŠ” μ§€μ—­ λ³€μˆ˜, 맀개 λ³€μˆ˜, 리턴 κ°’, μ—°μ‚° 쀑간 κ²°κ³Ό, 그리고 νž™ μ˜μ—­μ˜ 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” μ°Έμ‘° κ°’(μ£Όμ†Œ) 등이 μ €μž₯λœλ‹€.

PC Register μ˜μ—­κ³Ό λ™μΌν•˜κ²Œ μŠ€λ ˆλ“œλ‹Ή 1κ°œμ”© μƒμ„±λœλ‹€. λ˜ν•œ μŠ€λ ˆλ“œ μ’…λ£Œ μ‹œ ν•¨κ»˜ μ†Œλ©Έν•œλ‹€.

Native Method Stack

Native Method Stack은 μžλ°” μ½”λ“œκ°€ μ•„λ‹Œ, C/C++ λ“± λ„€μ΄ν‹°λΈŒ μ–Έμ–΄λ‘œ μž‘μ„±λœ λ©”μ„œλ“œ(native method)λ₯Ό μ‹€ν–‰ν•  λ•Œ μ‚¬μš©λ˜λŠ” μŠ€λ ˆλ“œλ³„ μŠ€νƒ μ˜μ—­μ΄λ‹€.

JVM은 JNI(Java Native Interface)λ₯Ό 톡해 λ„€μ΄ν‹°λΈŒ μ½”λ“œλ₯Ό ν˜ΈμΆœν•  수 있으며, μ΄λ•Œ μžλ°” λ°”μ΄νŠΈμ½”λ“œκ°€ μ•„λ‹Œ 기계어 μˆ˜μ€€μ˜ λ„€μ΄ν‹°λΈŒ μ½”λ“œ 싀행을 μœ„ν•œ λ³„λ„μ˜ 호좜 μŠ€νƒμ΄ μ‚¬μš©λœλ‹€.

이 μ˜μ—­μ€ 운영체제의 호좜 κ·œμ•½μ— 따라, ν•¨μˆ˜ 호좜 정보(리턴 μ£Όμ†Œ, λ§€κ°œλ³€μˆ˜, μ§€μ—­ λ³€μˆ˜ λ“±)λ₯Ό μ €μž₯ν•˜λ©°, 일반적인 C ν”„λ‘œκ·Έλž¨μ—μ„œ μ‚¬μš©ν•˜λŠ” μŠ€νƒ λ©”λͺ¨λ¦¬ ꡬ쑰와 맀우 μœ μ‚¬ν•˜κ²Œ λ™μž‘ν•œλ‹€.

이 μŠ€νƒ μ—­μ‹œ ν¬κΈ°μ—λŠ” μ œν•œμ΄ 있으며, κ³Όλ„ν•œ λ„€μ΄ν‹°λΈŒ ν˜ΈμΆœμ΄λ‚˜ μŠ€λ ˆλ“œ 생성 μ‹œ StackOverflowErrorλ‚˜ OutOfMemoryErrorκ°€ λ°œμƒν•  수 μžˆλ‹€.

ν† μŠ€ SLASH22 - Java Native Memory Leak 원인을 μ°Ύμ•„μ„œ

Method Area(=Static Area)

Method AreaλŠ” JVM이 클래슀 정보λ₯Ό 처음 λ©”λͺ¨λ¦¬μ— λ‘œλ“œν•  λ•Œ, ν•΄λ‹Ή 클래슀 μˆ˜μ€€μ˜ 정보λ₯Ό μ €μž₯ν•˜λŠ” μ˜μ—­μ΄λ‹€.

μ—¬κΈ°μ—λŠ” 클래슀 이름, λΆ€λͺ¨ 클래슀 정보, static λ³€μˆ˜, λ©”μ„œλ“œ 정보, μƒμˆ˜ ν’€(Runtime Constant Pool) 등이 μ €μž₯λœλ‹€.

λ˜ν•œ ν΄λž˜μŠ€κ°€ λ‘œλ”©λ  λ•Œ static ν•„λ“œμ˜ κΈ°λ³Έκ°’ ν• λ‹Ή 및 static 블둝 μ‹€ν–‰ μ „κΉŒμ§€μ˜ 정보가 이 μ˜μ—­μ— μ€€λΉ„λœλ‹€.

Runtime Constant Pool(λŸ°νƒ€μž„ μƒμˆ˜ ν’€)

클래슀 λ˜λŠ” μΈν„°νŽ˜μ΄μŠ€κ°€ μ‚¬μš©ν•˜λŠ” λ¦¬ν„°λŸ΄(λ¬Έμžμ—΄, 숫자 μƒμˆ˜ λ“±)μ΄λ‚˜ 기호 μ°Έμ‘° 정보(λ©”μ„œλ“œ/ν•„λ“œ μ°Έμ‘°, 클래슀 이름 λ“±)λ₯Ό μ €μž₯ν•˜λŠ” ꡬ쑰둜,
JVM이 λ°”μ΄νŠΈμ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λŠ” 데 ν•„μš”ν•œ λ‹€μ–‘ν•œ μƒμˆ˜ 및 μ°Έμ‘° 정보λ₯Ό μ œκ³΅ν•œλ‹€.

Heap

Heap은 μžλ°”μ—μ„œ 객체와 배열을 μ €μž₯ν•˜λŠ” λ©”λͺ¨λ¦¬ 곡간이닀.
new μ—°μ‚°μžλ₯Ό 톡해 μƒμ„±λœ λͺ¨λ“  κ°μ²΄λŠ” Heap에 μ €μž₯되며, κ°€λΉ„μ§€ 컬렉터(GC)의 관리 λŒ€μƒμ΄ λœλ‹€.

νž™μ€ λ‹€μŒκ³Ό 같이 μ„Έ λΆ€λΆ„μœΌλ‘œ λ‚˜λ‰œλ‹€.

1. Young Generation
μƒˆλ‘­κ²Œ μƒμ„±λœ 객체가 μ €μž₯λ˜λŠ” κ³΅κ°„μœΌλ‘œ, Minor GCκ°€ 자주 λ°œμƒν•˜μ—¬ 짧은 생λͺ…μ£ΌκΈ°μ˜ 객체λ₯Ό λΉ λ₯΄κ²Œ μ œκ±°ν•˜κ²Œ λœλ‹€.
Eden, Survivor μ˜μ—­(S0, S1)으둜 κ΅¬μ„±λœλ‹€.

2. Old Generation
Young μ˜μ—­μ„ μ§€λ‚˜ 살아남은 였래된 객체듀이 μ €μž₯λ˜λŠ” 곳이닀.
YG에 λΉ„ν•΄μ„œ μƒλŒ€μ μœΌλ‘œ GCκ°€ 적게 λ°œμƒν•˜λ©°, Major GC λ˜λŠ” Full GC의 λŒ€μƒμ΄ λœλ‹€.

3. Metaspace(Permanent Generation)
클래슀 메타정보가 μ €μž₯λ˜λŠ” κ³΅κ°„μœΌλ‘œ, JVM이 μ•„λ‹Œ OSκ°€ 직접 κ΄€λ¦¬ν•˜λŠ” λ„€μ΄ν‹°λΈŒ λ©”λͺ¨λ¦¬ 곡간을 μ‚¬μš©ν•œλ‹€.

μ™œ MetaspaceλŠ” λ„€μ΄ν‹°λΈŒ λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜λŠ”κ°€?

1. PermGen의 단점 보완 λͺ©μ 
Java 8 μ΄μ „μ—λŠ” PermGenμ΄λΌλŠ” κ³ μ •λœ 크기의 λ©”λͺ¨λ¦¬ μ˜μ—­μ„ μ‚¬μš©ν–ˆλŠ”λ°, 크기가 고정이라 OOM이 자주 λ°œμƒν•˜μ˜€λ‹€.

2. μœ μ—°ν•œ λ©”λͺ¨λ¦¬ μ‚¬μš©
Java 8λΆ€ν„° λ„μž…λœ MetaspaceλŠ” JVM λ‚΄λΆ€ λ©”λͺ¨λ¦¬ λŒ€μ‹ , OSκ°€ κ΄€λ¦¬ν•˜λŠ” λ„€μ΄ν‹°λΈŒ λ©”λͺ¨λ¦¬ μ˜μ—­μ„ μ‚¬μš©ν•˜κ²Œ λ˜μ—ˆλ‹€.
λ”°λΌμ„œ ν•„μš”ν•œ 만큼 λ™μ μœΌλ‘œ 증가할 수 μžˆμ–΄, PermGen보닀 훨씬 μ•ˆμ •μ μΈ λ©”λͺ¨λ¦¬ 관리λ₯Ό μ œκ³΅ν•œλ‹€.


μ°Έκ³ ν•œ λΈ”λ‘œκ·Έ 1
μ°Έκ³ ν•œ λΈ”λ‘œκ·Έ 2
μ°Έκ³ ν•œ λΈ”λ‘œκ·Έ 3

profile
μ•ˆλ…•ν•˜μ„Έμš”. λΉ„μ¦ˆλ‹ˆμŠ€λ₯Ό μ΄ν•΄ν•˜λŠ” λ°±μ—”λ“œ 개발자, ν•œμƒν˜Έμž…λ‹ˆλ‹€.

0개의 λŒ“κΈ€