Garbege Collector

가비지 객체 μ„ μ •

Java GC λŠ” 객체가 가비지 객체인지 νŒλ³„ν•˜κΈ° μœ„ν•΄μ„œ reachability λΌλŠ” κ°œλ…μ„ μ‚¬μš©ν•œλ‹€.
μ΄λŠ” μœ νš¨ν•œ μ°Έμ‘°κ°€ 있으면 reachable 둜, μ—†μœΌλ©΄ unreachable 둜 κ΅¬λ³„ν•˜κ³  unreachable 객체λ₯Ό κ°€λΉ„μ§€λ‘œ κ°„μ£Όν•˜μ—¬ GC λ₯Ό μˆ˜ν–‰ν•œλ‹€.

μ„œλ‘œ μ°Έμ‘°ν•˜κ³  μžˆλŠ” 객체듀을 μ°Έμ‘° μ‚¬μŠ¬ 이라고 ν•˜λ©° 졜쑰의 μ°Έμ‘°κ°€ 이루어져 μžˆλŠ” 객체의 μ°Έμ‘°λ₯Ό Root Set 이라고 ν•œλ‹€.

μ•„λž˜λŠ” λŸ°νƒ€μž„ 데이터 μ˜μ—­μ˜ ꡬ쑰이닀.

λŸ°νƒ€μž„ 데이터 μ˜μ—­1

Reachability

Heap μ˜μ—­μ— μžˆλŠ” 객체듀에 λŒ€ν•œ μ°Έμ‘°λŠ” λ‹€μŒ 4가지쀑에 ν•˜λ‚˜μ΄λ‹€.

  • Heap μ˜μ—­ 내에 μžˆλŠ” λ‹€λ₯Έ 객체에 μ˜ν•œ μ°Έμ‘°
  • Java Stack (Java Method μ‹€ν–‰μ‹œ μ‚¬μš©ν•˜λŠ” μ§€μ—­λ³€μˆ˜ 및 νŒŒλΌλ©”ν„°λ“€μ— μ˜ν•œ μ°Έμ‘°)
  • Native Stack (JNI에 μ˜ν•΄ μƒμ„±λœ 객체에 λŒ€ν•œ μ°Έμ‘°)
  • λ©”μ„œλ“œ μ˜μ—­μ˜ 정적 λ³€μˆ˜μ— μ˜ν•œ μ°Έμ‘°

이듀 쀑 Heap λ‚΄μ˜ λ‹€λ₯Έ 객체에 μ˜ν•œ μ°Έμ‘°λ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€ 3κ°œκ°€ Root Set 이 λ˜λ―€λ‘œ reachability 객체λ₯Ό νŒκ°€λ¦„ ν•˜λŠ” 기쀀이 λœλ‹€.

이λ₯Ό μ μš©ν•œ ꡬ성은 λ‹€μŒκ³Ό κ°™λ‹€.

λŸ°νƒ€μž„ 데이터 μ˜μ—­1

Root Set μ—μ„œ μ‹œμž‘ν•œ μ°Έμ‘° μ‚¬μŠ¬μ— μ†ν•œ 객체듀은 reachable 객체이고 이와 λ¬΄κ΄€ν•œ 객체듀을 unreachable 객체둜 GC λŒ€μƒμ΄λ‹€.

였λ₯Έμͺ½ μ•„λž˜ 객체처럼 reachable 객체λ₯Ό μ°Έμ‘°ν•˜λ”λΌλ„, λ‹€λ₯Έ reachable 객체가 이 객체λ₯Ό μ°Έμ‘°ν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ 이 κ°μ²΄λŠ” unreachable 객체이닀. (이 κ·Έλ¦Όμ—μ„œ μ°Έμ‘°λŠ” λͺ¨λ‘ java.lang.ref νŒ¨ν‚€μ§€λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ€ 일반적인 참쑰이닀.)

μœ„ ꡬ성을 strong reference 라 λΆ€λ₯Έλ‹€.

Reference Object

java.lang.ref λŠ” soft, weak, phantom reference λ₯Ό 클래슀 ν˜•νƒœλ‘œ μ œκ³΅ν•œλ‹€.

java.lang.ref.WeakReference ν΄λž˜μŠ€λŠ” μ°Έμ‘° λŒ€μƒμΈ 객체λ₯Ό μΊ‘μŠν™”ν•œ WeakReference 객체λ₯Ό μƒμ„±ν•œλ‹€.
μ΄λ ‡κ²Œ μƒμ„±ν•œ κ°μ²΄λŠ” Java GC 의 별도 관리 λŒ€μƒμ΄ λœλ‹€. (μΊ‘μŠν™”λœ λ‚΄λΆ€ κ°μ²΄λŠ” weak reference 에 μ˜ν•΄ μ°Έμ‘°λœλ‹€.)

WeakReference<Sample> wr = new WeakReference<Sample>(new Sample());
Sample ex = wr.get();

Weak Reference1

μœ„ μ½”λ“œμ—μ„œ WeakReference 클래슀의 κ°μ²΄λŠ” new λ©”μ„œλ“œλ‘œ μƒμ„±λœ Sample 객체λ₯Ό μΊ‘μŠν™”ν•œ 객체이닀.
참쑰된 Sample κ°μ²΄λŠ” λ‘λ²ˆμ§Έ μ€„μ—μ„œ get λ©”μ„œλ“œμ— μ˜ν•΄ λ‹€λ₯Έ 참쑰에 λŒ€μž…λœλ‹€.

이 μ‹œμ μ—μ„œ WeakReference 객체 λ‚΄μ˜ 참쑰와 ex μ°Έμ‘°κ°€ Sample 객체λ₯Ό κ°€λ₯΄ν‚¨λ‹€.

ex = null;

Weak Reference2

μœ„ μ½”λ“œμ™€ 같이 ex 참쑰에 null 을 λŒ€μž…ν•˜λ©΄ 처음 μƒμ„±ν•œ Sample κ°μ²΄λŠ” 였직 WeakReference λ‚΄λΆ€μ—μ„œλ§Œ μ°Έμ‘°λœλ‹€.

이λ₯Ό weakly reachable μƒνƒœ 객체 라고 ν•œλ‹€.

Reference Object
Java μŠ€νŒ©μ—μ„œ SoftReference, WeakReference, PhantomReference 3가지 클래슀둜 μƒμ„±λœ 객체λ₯Ό λ§ν•œλ‹€.
Reference Object 에 μ˜ν•΄ 참쑰된 객체λ₯Ό referent 라고 ν•œλ‹€.

Reference와 Reachability

μœ„μ—μ„œ GC λŒ€μƒμ—¬λΆ€λ₯Ό reachable, unreachable 둜 κ΅¬λΆ„ν•˜μ˜€μœΌλ©°
java.lang.ref νŒ¨ν‚€μ§€λ₯Ό μ΄μš©ν•˜μ—¬ GC λ•Œμ˜ λ™μž‘μ„ λ‹€λ₯΄κ²Œ 지정가λŠ₯ν•˜κ²Œλ” κ°œμž… ν•  수 μžˆλ‹€.
이λ₯Ό λ‹€μŒκ³Ό 같이 ν‘œν˜„ κ°€λŠ₯ν•˜λ‹€.

Weak Reference3

  • νŒŒλž‘ : Strongly Reachable Object
  • 녹색 : Weakly Reachable Object (GC λŒ€μƒ)
  • λΉ¨κ°• : Unreachable Object (GC λŒ€μƒ)

μœ„ κ·Έλ¦Όμ—μ„œ WeakReference 객체 μžμ²΄λŠ” weakly reachable 객체가 μ•„λ‹ˆλΌ strongly reachable 객체이닀.
λ˜ν•œ WeakReference 에 μ˜ν•΄ 참쑰되고 μžˆμœΌλ©΄μ„œ λ™μ‹œμ— root set μ—μ„œ μ‹œμž‘ν•œ μ°Έμ‘°μ‚¬μŠ¬μ— ν¬ν•¨λ˜μ–΄ μžˆλŠ” 경우 weakly reachable 객체가 μ•„λ‹ˆλΌ strongly reachable 객체이닀.

GCκ°€ λ™μž‘ν•˜μ—¬ μ–΄λ–€ 객체λ₯Ό weakly reachable 객체둜 판λͺ…ν•˜λ©΄,
GCλŠ” WeakReference 객체에 μžˆλŠ” weakly reachable 객체에 λŒ€ν•œ μ°Έμ‘°λ₯Ό null 둜 μ„€μ •ν•œλ‹€.

이에 따라 weakly reachable κ°μ²΄λŠ” unreachable 객체와 λ§ˆμ°¬κ°€μ§€ μƒνƒœκ°€ 되고,
κ°€λΉ„μ§€λ‘œ 판λͺ…λœ λ‹€λ₯Έ 객체듀과 ν•¨κ»˜ λ©”λͺ¨λ¦¬ 회수 λŒ€μƒμ΄ λœλ‹€.

Strengths of Reachability

Java GC λŠ” μœ„μ—μ„œ λ§ν•œ κ·Όκ±°λ₯Ό λ°”νƒ•μœΌλ‘œ λ‹€μŒ 5κ°€μ§€μ˜ Reachability λ₯Ό κ²°μ •ν•œλ‹€.

  • Strongly Reachable
    • root set 으둜 λΆ€ν„° μ‹œμž‘ν•΄μ„œ μ–΄λ–€ reference object 도 쀑간에 끼어 μžˆμ§€ μ•ŠλŠ” μƒνƒœ
    • κ°μ²΄κΉŒμ§€ λ„λ‹¬ν•˜λŠ” μ—¬λŸ¬ μ°Έμ‘°μ‚¬μŠ¬μ€‘μ— reference object κ°€ ν•˜λ‚˜λΌλ„ μ—†λŠ” 객체
  • Softly Reachable
    • Strongly Reachable 객체가 μ•„λ‹Œ 객체쀑에 weak reference, phantom reference 없이 sort reference κ°€ ν•˜λ‚˜λΌλ„ μžˆλŠ” 객체
  • Weakly Reachable
    • Strongly Reachable λ‚˜ Softly Reachable 객체도 μ•„λ‹Œ κ°μ²΄μ€‘μ—μ„œ phantom reference 없이 weak reference 만 ν†΅κ³Όν•˜λŠ” μ°Έμ‘° μ‚¬μŠ¬μ΄ ν•˜λ‚˜λΌλ„ μžˆλŠ” 객체
  • Phantomly Reachable
    • Strongly Reachable λ‚˜ Softly Reachable, Weakly Reachable 객체 λͺ¨λ‘ ν•΄λ‹Ήλ˜μ§€ μ•ŠλŠ” 객체
    • finalize λ˜μ—ˆμ§€λ§Œ 아직 λ©”λͺ¨λ¦¬κ°€ νšŒμˆ˜λ˜μ§€ μ•ŠλŠ” μƒνƒœ
  • Unreachable
    • root set 으둜 λΆ€ν„° μ‹œμž‘λ˜λŠ” μ°Έμ‘° μ‚¬μŠ¬μ΄ μ°Έμ‘°λ˜μ§€ μ•ŠλŠ” μƒνƒœ

μ•„λž˜ μ˜ˆμ‹œμ˜ 객체 B λŠ” Softly Reachable 이닀.

Softly Reachable

μ˜μ—­ ꡬ성

GC λ₯Ό μ‹€ν–‰ν•˜κΈ° μœ„ν•΄ stop-the-world 을 μ΄μš©ν•˜μ—¬ λͺ¨λ“  μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μž‘μ—…μ„ λ©ˆμΆ˜λ‹€.
이 stop-the-world λ₯Ό μ‹€ν–‰ν•˜λ©΄ GC λ₯Ό μ‹€ν–‰ν•˜λŠ” thread λ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€ thread λŠ” λͺ¨λ‘ μž‘μ—…μ„ λ©ˆμΆ˜λ‹€.

GC μž‘μ—…μ„ μ™„λ£Œν•œ μ΄ν›„μ—λŠ” μ€‘λ‹¨λ¬λ˜ μž‘μ—…μ„ λ‹€μ‹œ μ‹œμž‘ν•œλ‹€.

JAVA ν”„λ‘œκ·Έλž¨ μ½”λ“œμ—μ„œλŠ” λ©”λͺ¨λ¦¬λ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ§€μ •ν•˜μ—¬ ν•΄μ œν•˜μ§€ μ•ŠλŠ”λ‹€.
μ΄λŠ” Garbage Collector μ˜ν•΄ 더 이상 ν•„μš”μ—†λŠ” 객체λ₯Ό μ°Ύμ•„ μ§€μš°λŠ” μž‘μ—…μ„ ν•œλ‹€.

이 Garbage Collector 의 섀계 원칙은 weak generational hypothesis 이라고 ν•˜λŠ”λ° 이 원칙은 λ‹€μŒκ³Ό κ°™λ‹€.

  • λŒ€λΆ€λΆ„μ˜ κ°μ²΄λŠ” 금방 μ ‘κ·Ό λΆˆκ°€λŠ₯ν•œ μƒνƒœ (unreachable) μƒνƒœκ°€ λœλ‹€.
  • 였래된 κ°μ²΄μ—μ„œ μ Šμ€ κ°μ²΄λ‘œμ„œμ˜ μ°Έμ‘°λŠ” 극히 λ“œλ¬Όλ‹€.

μœ„ 두 가섀을 κΈ°λ°˜μœΌλ‘œν•œ HotSpot VM μ—μ„œλŠ” 크게 2개의 물리적 곡간을 λ‚˜λ‰˜μ—ˆλ‹€.
λ°”λ‘œ μ•„λž˜μ™€ 같은 Old Generation Area, Young Generation Area 이닀.

GC μ˜μ—­ 및 데이터 흐름도

Young Generation Area

  • μƒˆλ‘­κ²Œ μƒμ„±ν•œ 객체가 μœ„μΉ˜ν•˜λŠ” 곡간
  • λŒ€λΆ€λΆ„μ˜ 객체가 금방 μ ‘κ·Ό λΆˆκ°€ μƒνƒœκ°€ 되기 λ•Œλ¬Έμ— λ§Žμ€ 객체가 Young μ—μ„œ μƒμ„±λ˜μ—ˆλ‹€κ°€ 사라진닀
  • 이 μ˜μ—­μ—μ„œ 객체가 μ‚¬λΌμ§ˆλ•Œ Minor GC κ°€ λ°œμƒν•œλ‹€.

Old Generation Area

  • μ ‘κ·Ό λΆˆκ°€λŠ₯ μƒνƒœλ‘œ λ˜μ§€ μ•Šμ•„ Young μ˜μ—­μ—μ„œ 살아남은 객체가 μ—¬κΈ°λ‘œ λ³΅μ‚¬λœλ‹€.
  • λŒ€λΆ€λΆ„μ˜ Young μ˜μ—­λ³΄λ‹€ 크게 ν• λ‹Ήν•˜λ©°, Young μ˜μ—­ λ³΄λ‹€λŠ” GC κ°€ 적게 λ°œμƒν•œλ‹€.
  • 이 μ˜μ—­μ—μ„œ 객체가 μ‚¬λΌμ§ˆλ•Œ Major GC (ν˜Ήμ€ Full GC) κ°€ λ°œμƒν•œλ‹€.

Permanent Generation Area

  • κ°μ²΄λ‚˜ μ–΅λ₯˜λœ λ¬Έμžμ—΄ 정보λ₯Ό μ €μž₯ν•˜λŠ” κ³³
  • 이 μ˜μ—­μ—μ„œ 객체가 μ‚¬λΌμ§ˆλ•Œ Major GC κ°€ λ°œμƒν•œλ‹€.

Old μ˜μ—­μ—μ„œ Young μ˜μ—­ μ°Έμ‘°κ°€ μΌμ–΄λ‚ λ•ŒλŠ” Card Table μ΄λΌλŠ” μ˜μ—­μ„ μ‚¬μš©ν•œλ‹€.

Young μ˜μ—­ ꡬ성

Young μ˜μ—­μ€ λ‹€μŒ 3개의 μ˜μ—­μœΌλ‘œ κ΅¬μ„±λœλ‹€.

  • Eden Area (1개)
  • Survivor Area (2개)

Young μ˜μ—­ GC μ „ν›„

  • μƒˆλ‘œ μƒμ„±ν•œ λŒ€λΆ€λΆ„μ˜ κ°μ²΄λŠ” Eden μ˜μ—­μ— μœ„μΉ˜ν•œλ‹€.
  • Eden μ˜μ—­μ—μ„œ GC κ°€ ν•œλ²ˆ λ°œμƒν•œ ν›„ 살아남은 κ°μ²΄λŠ” Survivor μ˜μ—­ 쀑 ν•˜λ‚˜λ‘œ μ΄λ™λœλ‹€.
  • ν•˜λ‚˜μ˜ Survivor μ˜μ—­μ΄ 가득 차게되면 그쀑 살아남은 객체λ₯Ό λ‹€λ₯Έ Survivor μ˜μ—­μœΌλ‘œ μ΄λ™ν•˜κ³  가득찬 Survivor μ˜μ—­μ€ 아무데이터도 μ—†λŠ” μƒνƒœκ°€ λœλ‹€.
  • 이 과정을 λ°˜λ³΅ν•˜λ©° 살아남은 κ°μ²΄λŠ” Old μ˜μ—­μœΌλ‘œ μ΄λ™ν•˜κ²Œ λœλ‹€.

Survivor μ˜μ—­ 쀑 ν•˜λ‚˜λŠ” λ°˜λ“œμ‹œ λΉ„μ–΄μžˆλŠ” μƒνƒœλ‘œ 남아 μžˆμ–΄μ•Ό ν•œλ‹€. λ§Œμ•½ 두 Survivor μ˜μ—­μ΄ λͺ¨λ‘ 데이터가 μ‘΄μž¬ν•˜κ±°λ‚˜, λ‘κ°œμ˜ Survivor μ˜μ—­μ˜ μ‚¬μš©λŸ‰μ΄ 0 이라면 μ‹œμŠ€ν…œμ€ 정상적인 상황이 μ•„λ‹ˆλ‹€.

HotSpot VM 의 λ©”λͺ¨λ¦¬ ν• λ‹Ή 기술

Young μ˜μ—­μ—λŠ” 객체의 이동이 λΉˆλ²ˆν•˜κΈ° λ•Œλ¬Έμ— κ°œμ„ λœ λ©”λͺ¨λ¦¬ ν• λ‹Ή 기술이 ν•„μš”ν•˜λ‹€.
λ‹€μŒμ€ HotSpot VM μ—μ„œ μ‚¬μš©μ€‘μΈ 2κ°€μ§€μ˜ λ©”λͺ¨λ¦¬ ν• λ‹Ή κΈ°μˆ μ΄λ‹€.

  • bump-the-pointer
    • Eden μ˜μ—­μ— ν• λ‹Ήλœ λ§ˆμ§€λ§‰ 객체λ₯Ό μΆ”μ ν•œλ‹€.
    • λ§ˆμ§€λ§‰ κ°μ²΄λŠ” TOP 에 μœ„μΉ˜ν•˜κ³  있기 λ•Œλ¬Έμ— μ‚½μž…ν•˜λ €λŠ” 객체의 크기가 Eden μ˜μ—­μ— 넣기에 μ λ‹Ήν•œμ§€ ν™•μΈν•˜μ—¬ μΆ”κ°€ν•œλ‹€.
    • μƒˆλ‘œμš΄ 객체λ₯Ό μƒμ„±ν• λ•Œ λ§ˆμ§€λ§‰μ— μΆ”κ°€λœ 객체만 μ κ²€ν•˜λ©΄ λ˜λ―€λ‘œ 맀우 λΉ λ₯΄κ²Œ λ©”λͺ¨λ¦¬ 할당이 이루어진닀.
  • TLABs (Thread Local Allocation Buffers)
    • Multi Thread ν™˜κ²½μ—μ„œ Tread-Safe ν•˜κΈ° μœ„ν•΄μ„œ Eden μ˜μ—­μ— Lock 이 λ°œμƒ ν• μˆ˜ 밖에 μ—†λŠ”λ° 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œ HotSpot VM μ—μ„œ μ§€μ›ν•˜λŠ” TLABs 기술이 μžˆλ‹€.

Old μ˜μ—­μ˜ GC

Old μ˜μ—­μ€ 데이터가 가득차면 GC λ₯Ό μ‹€ν–‰ν•œλ‹€.
λ‹€μŒ GCλŠ” JDK 7 κΈ°μ€€μ˜ 5가지 방법이닀.

  • Serial GC
    • CPU μ½”μ–΄ κ°œμˆ˜κ°€ 적을 λ•Œ 적합
  • Parallel GC
    • λ©”λͺ¨λ¦¬μ™€ CPU μ½”μ–΄ κ°œμˆ˜κ°€ λ§Žμ„ λ•Œ 유리
  • Parallel Old GC (Parallel Compacting GC)
  • Concurrent Mark & Sweep GC (CMS)
    • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 응닡이 μ€‘μš”ν•œ 경우 μ‚¬μš© (Low Latency GC)
    • λ‹€λ₯Έ GC 에 λΉ„ν•΄ λ©”λͺ¨λ¦¬μ™€ CPU λ₯Ό 더 많이 μ‚¬μš©
    • λ‹€λ₯Έ GC 에 λΉ„ν•΄ μ‚°μž¬λœ λ©”λͺ¨λ¦¬κ°€ λ§Žμ„μˆ˜ 있기 λ•Œλ¬Έμ— stop-the-world μ‹œκ°„μ΄ 더 κΈΈλ‹€.
  • G1 (Garbage First) GC
    • κ°€μž₯ μ΅œμ‹ μ˜ κ°€μž₯ μ„±λŠ₯이 쒋은 GC (JDK 7 이상)