Language/Java

[Java] Java GC μ‰½κ²Œ μ΄ν•΄ν•˜κΈ°

jaee_ 2021. 10. 15. 03:18
βœ‹πŸ» λ“€μ–΄κ°€λ©°.. 
 κΈ°μ‘΄μ—λŠ” μ±… λ‚΄μš©μ„ κ·ΈλŒ€λ‘œ μž‘μ„±ν•˜κ³ (거의 ν•„μ‚¬μˆ˜μ€€,,) λ‚˜ μžμ‹ μ΄ μ΄ν•΄ν•˜κΈ° μœ„ν•΄μ„œ λΈ”λ‘œκ·Έ 글을 μž‘μ„±ν–ˆλ‹€λ©΄,  μ΄μ œλŠ” λ‚¨μ—κ²Œ μ„€λͺ…ν•˜λ“―이 λΈ”λ‘œκ·Έ 글을 μž‘μ„±ν•˜λ € ν•©λ‹ˆλ‹€. 이전 κΈ€λ“€κ³Ό μ„œμˆ  방식이 λ‹€λ₯Ό 수 μžˆμŠ΅λ‹ˆλ‹€. 

GCλž€

 

μš°λ¦¬λŠ” Java ν”„λ‘œκ·Έλž˜λ°μ„ ν•˜λ©΄μ„œ newλΌλŠ” ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. 이 λ•Œ newκ°€ 뢙은 κ°μ²΄λŠ” Heap μ˜μ—­μ— λ™μ μœΌλ‘œ λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•΄μ€λ‹ˆλ‹€. μ΄λ ‡κ²Œ λ™μ μœΌλ‘œ ν• λ‹Ήλœ λ©”λͺ¨λ¦¬λŠ” 더 이상 μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©΄ ν•΄μ œλ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. ν•΄μ œν•˜μ§€ μ•ŠμœΌλ©΄ λ©”λͺ¨λ¦¬λ₯Ό κ³„μ†ν•΄μ„œ μ μœ ν•˜κ³  μžˆμœΌλ―€λ‘œ OutOfMemmory Exception 이 λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λ ‡κ²Œ λ™μ μœΌλ‘œ ν• λ‹Ήλœ λ©”λͺ¨λ¦¬λ₯Ό ν•΄μ œν•΄μ£ΌλŠ” μž‘μ—…μ„ ν•˜λŠ” 것이 GCμž…λ‹ˆλ‹€. μ •λ¦¬ν•˜μžλ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

 

GCλž€ Garbage Collection(μ΄ν•˜ GC)의 μ•½μžλ‘œ λ” μ΄μƒ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”(μ“°λ ˆκΈ°) κ°μ²΄λ₯Ό μ°Ύμ•„ μ§€μš°λŠ” μž‘업을 ν•œλ‹€.

 

JavaλŠ” GCκ°€ λ©”λͺ¨λ¦¬λ₯Ό μžλ™μœΌλ‘œ κ΄€λ¦¬ν•΄μ€λ‹ˆλ‹€. λ§Œμ•½ GCκ°€ μ—†μ—ˆλ‹€λ©΄ κ°œλ°œμžκ°€ μˆ˜λ™μœΌλ‘œ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” λ©”λͺ¨λ¦¬λ₯Ό μ²΄ν¬ν•˜κ³  λ°˜ν™˜ν•˜λŠ” 일을 μˆ˜ν–‰ν•΄μ•Ό ν•©λ‹ˆλ‹€.

μƒκ°λ§Œ 해도 λ²ˆκ±°λ‘­μŠ΅λ‹ˆλ‹€. μžλ™μœΌλ‘œ λ©”λͺ¨λ¦¬λ₯Ό κ΄€λ¦¬ν•œλ‹€λŠ” 것이 μ–΄λ–€ κ΄€μ μ—μ„œ 보면 λΉ„νš¨μœ¨μ μ΄μ–΄ 보일 μˆ˜λ„ μžˆμ§€λ§Œ, 개발자 μž…μž₯에선 κ°œλ°œμ— 집쀑할 수 μžˆλŠ” ν™˜κ²½μ„ λ§Œλ“€μ–΄ μ€€λ‹€λŠ” μž₯점이 μžˆμŠ΅λ‹ˆλ‹€.

πŸ’‘ Javaμ—μ„œλ„ GCλ₯Ό κ°œλ°œμžκ°€ 직접 ν˜ΈμΆœν•˜λŠ” 방법도 μžˆμŠ΅λ‹ˆλ‹€. λ°”λ‘œ System.gc() λ©”μ†Œλ“œ μž…λ‹ˆλ‹€. ν•˜μ§€λ§Œ ν•΄λ‹Ή λ©”μ†Œλ“œλŠ” μ‹œμŠ€ν…œμ˜ μ„±λŠ₯에 큰 영ν–₯을 λ―ΈμΉ˜λ―€λ‘œ μ ˆλŒ€ ν˜ΈμΆœν•΄μ„œλŠ” μ•ˆλ©λ‹ˆλ‹€. κ·Έλƒ₯ GCκ°€ μ•Œμ•„μ„œ λ™μž‘ν•˜λ„λ‘ λ†”λ‘λŠ” 것이 제일 λ² μŠ€νŠΈμž…λ‹ˆλ‹€.

Stop-the-world


stop-the-worldλž€, GCλ₯Ό μ‹€ν–‰ν•˜κΈ° μœ„ν•΄ JVM이 μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 싀행을 λ©ˆμΆ”λŠ” 것 μž…λ‹ˆλ‹€. GCλ₯Ό μˆ˜ν–‰ν•˜λŠ” λ©”μ†Œλ“œλ₯Ό μ œμ™Έν•œ λͺ¨λ“  μ“°λ ˆλ“œκ°€ μΌμ‹œμ μœΌλ‘œ μ •μ§€λ˜λ©°, GCκ°€ λλ‚œ 뒀에야 μ •μ§€λλ˜ μ“°λ ˆλ“œκ°€ μ •μƒμ μœΌλ‘œ λ™μž‘ν•©λ‹ˆλ‹€.

μ–΄λ– ν•œ μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜μ—¬ GCλ₯Ό μˆ˜ν–‰ν•˜λ“  Stop-and-world μƒνƒœλ₯Ό λ§žμ΄ν•˜κ²Œ λ©λ‹ˆλ‹€. GC νŠœλ‹μ΄λΌν•˜λ©΄ 이와 같은 μ“°λ ˆλ“œμ˜ μž‘μ—…μ΄ λ©ˆμΆ”λŠ” μ‹œκ°„(Stop-and-world)을 μ΅œμ†Œν•œμœΌλ‘œ μ€„μ΄λŠ” 것이라고 보면 λ©λ‹ˆλ‹€.

 


Reachability

 

Java 의 GCλŠ” Reachability 의 κ°œλ…μ„ μ•Œμ•„μ•Όν•©λ‹ˆλ‹€. μ–΄λ– ν•œ 객체에 μœ νš¨ν•œ μ°Έμ‘°κ°€ μžˆλ‹€λ©΄ reachable μ΄λΌν•˜κ³ , μœ νš¨ν•œ μ°Έμ‘°κ°€ μ—†λ‹€λ©΄ unreachable이라 ν•©λ‹ˆλ‹€.

GCμ—λŠ” GC rootκ°€ μ‘΄μž¬ν•©λ‹ˆλ‹€. GC rootλŠ” 말 κ·ΈλŒ€λ‘œ GC의 뿌리라고 μ΄ν•΄ν•˜λ©΄ λ©λ‹ˆλ‹€.

βœ” GC rootκ°€ λ˜λŠ” 쑰건
1. stack μ˜μ—­μ˜ 데이터(μ§€μ—­λ³€μˆ˜, νŒŒλΌλ―Έν„° λ“±)
2. method μ˜μ—­μ˜ static 데이터
3. 싀행쀑인 μ“°λ ˆλ“œ
4. JNI (Java Native Interface)에 μ˜ν•΄ μƒμ„±λœ 객체

image

μœ„μ˜ μ‚¬μ§„μ—μ„œ λ³΄μ΄λŠ” 것 처럼 GC Root와 μ—°κ²°λœ κ°μ²΄λŠ” reachable κ·Έ μ™ΈλŠ” unreachable 이라고 ν•©λ‹ˆλ‹€. μ•„λž˜μ˜ 그림을 톡해 이해λ₯Ό 도와보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

image

 

μœ„μ˜ μ‚¬μ§„μ—μ„œ 1,3,4,5 λŠ” reachableν•œ μƒνƒœμž…λ‹ˆλ‹€.

  • 1,5 λŠ” Stack μ˜μ—­μ— μžˆλŠ” 6, 7을 μ°Έμ‘°ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
  • 3 은 Method Area μ˜μ—­μ— μžˆλŠ” 8을 μ°Έμ‘°ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
  • 4 λŠ” 7을 μ°Έμ‘°ν•˜κ³  μžˆλŠ” 5λ₯Ό μ°Έμ‘°ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

unreachable ν•œ 2 λŠ” 아무것도 μ°Έμ‘°ν•˜κ³  μžˆμ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 즉, GC의 수거 λŒ€μƒμ΄ λ©λ‹ˆλ‹€.


🀷‍♂️ 그럼 GC의 μ–΄λ–€ μ•Œκ³ λ¦¬μ¦˜μ— μ˜ν•΄ λ™μž‘ν•˜μ§€?

 

λ°”λ‘œ Mark and Sweep μ΄λΌλŠ” μ•Œκ³ λ¦¬μ¦˜μœΌλ‘œ λ™μž‘ν•©λ‹ˆλ‹€.

GC rootμ—μ„œ μ‹œμž‘ν•˜μ—¬ rootκ°€ μ°Έμ‘°ν•˜λŠ” λͺ¨λ“  객체 λ˜λŠ” κ·Έ 객체듀이 μ°Έμ‘°ν•˜λŠ” λ‹€λ₯Έ 객체듀을 νƒμƒ‰ν•˜λ©° 마크(Mark)ν•©λ‹ˆλ‹€. 이 과정이 Mark and Sweep μ•Œκ³ λ¦¬μ¦˜μ˜ Mark에 ν•΄λ‹Ήν•©λ‹ˆλ‹€.

image



[참쑰된 개체 : νŒŒλž€μƒ‰ / μ°Έμ‘°λ˜μ§€ μ•Šμ€ 개체 : λ…Έλž€μƒ‰]

Markκ°€ λλ‚˜λ©΄ GCλŠ” 마크(Mark)λ˜μ§€ μ•Šμ€ λ©”λͺ¨λ¦¬λ“€μ„ ν•΄μ œν•©λ‹ˆλ‹€. 이 과정을 Sweep이라고 ν•©λ‹ˆλ‹€.

image



[참쑰되고 μžˆμ§€ μ•Šμ€ 개체λ₯Ό μ‚­μ œ ν•œ ν›„μ˜ κ·Έλ¦Όμž…λ‹ˆλ‹€. ]

Mark and Sweep μ•Œκ³ λ¦¬μ¦˜ 뿐만 μ•„λ‹ˆλΌ compact λΌλŠ” μ•Œκ³ λ¦¬μ¦˜λ„ μžˆμŠ΅λ‹ˆλ‹€. compactλŠ” Mark and Sweep 과정을 거치고 λ‚˜λ©΄ Mark λ˜μ§€ μ•Šμ€ κ°μ²΄λ“€λ§Œ λ‚¨μ•„μžˆμ„ 것 μž…λ‹ˆλ‹€. 그러면 객체듀이 듬성듬성 μ‘΄μž¬ν•˜κ² μ£ ? μ΄λŸ¬ν•œ 객체듀을 μ••μΆ•, 즉 ν•œ 곳으둜 λͺ¨μ•„μ„œ λ©”λͺ¨λ¦¬ λ‹¨νŽΈν™”λ₯Ό λ§‰μŠ΅λ‹ˆλ‹€. compact 과정을 톡해 μƒˆ λ©”λͺ¨λ¦¬ 할당이 쉽고, 빨라지도둝 ν•©λ‹ˆλ‹€.

image


[Sweep κ³Όμ • ν›„ 듬성듬성 μ‘΄μž¬ν•˜λŠ” 참쑰된 개체 μ••μΆ•ν•œ λͺ¨μŠ΅]


πŸ” κ·Έλž˜μ„œ μ € μ•Œκ³ λ¦¬μ¦˜μ΄ μ–Έμ œ λ™μž‘ν•˜λŠ”λ°?

 

GCλŠ” Heap μ˜μ—­μ— λ™μ μœΌλ‘œ ν• λ‹Ήλœ λ©”λͺ¨λ¦¬ 쀑 더 이상 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” λ©”λͺ¨λ¦¬λ₯Ό μžλ™μœΌλ‘œ ν•΄μ œν•΄μ€€λ‹€κ³  ν–ˆμŠ΅λ‹ˆλ‹€.

Heap μ˜μ—­μ— λŒ€ν•΄ μ•Œμ•„λ³΄λ„λ‘ ν•˜μ£ . Heap μ˜μ—­μ€ μ•„λž˜μ˜ 사진과 같이 λ‚˜λ‰©λ‹ˆλ‹€.

image

  • Young Generation : μ Šμ€ 객체
    • eden : 객체λ₯Ό μƒμ„±ν•˜μžλ§ˆμž μ €μž₯λ˜λŠ” μž₯μ†Œ
    • Survivor Space 0 : κ°μ‹œμž 0
    • Survivor Space 1 : κ°μ‹œμž 2
  • Old Generation : 였래된 객체
  • Parameter Generation

크게 Young Generation, Old Generation, Parameter Generation 으둜 λ‚˜λ‰˜λ©° Young Generation 은 eden , Survivor Space 0 , Survivor Space 1 둜 또 λ‚˜λ‰©λ‹ˆλ‹€.

Heap μ˜μ—­ λ©”λͺ¨λ¦¬κ°€ μ–΄λ–»κ²Œ λ‚˜λ‰˜λŠ”μ§€ μ‚΄νŽ΄λ΄€μœΌλ‹ˆ 이제 Heap μ˜μ—­μ— 객체가 μƒμ„±λ˜κ³  GCκ°€ μΌμ–΄λ‚˜λŠ” 과정을 μ‚΄νŽ΄λ³΄λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€. μš°λ¦¬κ°€ 객체λ₯Ό μƒμ„±ν•˜μžλ§ˆμž μ €μž₯λ˜λŠ” μž₯μ†ŒλŠ” Eden μ˜μ—­μž…λ‹ˆλ‹€.

  1. Eden μ˜μ—­μ— 객체가 μƒμ„±λ©λ‹ˆλ‹€.
  2. Eden μ˜μ—­μ΄ 꽉 μ°¨λ©΄ Minor GC(λ§ˆμ΄λ„ˆ GC)κ°€ λ°œμƒ(Mark-and-Sweep)ν•©λ‹ˆλ‹€.
  3. μ‚΄μ•„μžˆλŠ” 객체만 Survivor 0 μ˜μ—­μœΌλ‘œ λ³΅μ‚¬λ˜κ³ ,
  4. λ‹€μ‹œ Eden μ˜μ—­μ„ μ±„μš°κ²Œ λ©λ‹ˆλ‹€.
  5. Survivor 0 μ˜μ—­μ΄ 꽉 차게 되면 Survivor 1 μ˜μ—­μœΌλ‘œ 객체가 λ³΅μ‚¬λ©λ‹ˆλ‹€.
  6. 이 λ•Œ, Eden μ˜μ—­μ— μžˆλŠ” 객체듀 쀑 μ‚΄μ•„μžˆλŠ” 객체듀도 Survivor 1 μ˜μ—­μœΌλ‘œ κ°‘λ‹ˆλ‹€. 즉, Survivor 0 λ˜λŠ” 1 λ‘˜ 쀑 ν•˜λ‚˜λŠ” λ°˜λ“œμ‹œ λΉ„μ›Œμ Έ μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.
  7. 1~4κ°€ 반볡될 λ•Œλ§ˆλ‹€ μ‚΄μ•„μžˆλŠ” κ°μ²΄λŠ” age값이 μ¦κ°€ν•©λ‹ˆλ‹€.
  8. 일정 μˆ˜μ€€μ˜ age값에 λ„λ‹¬ν•˜λ©΄ Young Generationμ—μ„œ Old Generation으둜 μ΄λ™ν•©λ‹ˆλ‹€.
  9. 1~5κ°€ λ°˜λ³΅ν•˜λ‹€λ³΄λ©΄ Old Generation도 꽉 차게 λ©λ‹ˆλ‹€. 이 λ•Œ major GC(메이저 GC) κ°€ λ°œμƒν•˜κ²Œ λ©λ‹ˆλ‹€. (Full GC 라고도 λΆˆλ¦°λ‹€.)

μœ„μ˜ 과정을 사진을 톡해 이해해 보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

image

μœ„μ˜ 사진은 1~4 κΉŒμ§€μ˜ κ³Όμ •μž…λ‹ˆλ‹€. μœ„μ˜ 과정을 λ°˜λ³΅ν•˜λ©° 였래된 객체(ageκ°’μœΌλ‘œ νŒλ‹¨)λŠ” Old Generation으둜 μ΄λ™ν•˜κ²Œ λ©λ‹ˆλ‹€. (μ•„λž˜μ˜ 사진 μ°Έκ³ )

image

κ·Έλ ‡κ²Œ Old GenerationκΉŒμ§€ 꽉차면 메이저 GCκ°€ λ°œμƒν•˜κ²Œ λ˜λŠ” 것 μž…λ‹ˆλ‹€.

πŸ’‘ minor GC vs major GC λˆ„κ°€ 더 λΉ λ₯ΌκΉŒ?
 --> 닡은 minor GC!! 
 μ΄μœ λŠ” 일반적으둜 더 μž‘μ€ 곡간이 ν• λ‹Ήλ˜κ³ , 객체듀을 μ²˜λ¦¬ν•˜λŠ” 방식도 λ‹€λ₯΄κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. 

 


🀷‍♂️ μ™œ GCλ₯Ό λ‚˜λˆ„λ‚˜μš”..

 

κ·Έλƒ₯ ν•œ λ²ˆμ— GCλ₯Ό μ§„ν–‰ν•˜λ©΄ 될 것을 μ™œ λ‚˜λˆ„μ—ˆμ„κΉŒμš”?

GC μ„€κ³„μžλ“€μ€ 두 κ°€μ§€μ˜ 가섀을 μ „μž¬ν•˜κ³  GCλ₯Ό λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

  • λŒ€λΆ€λΆ„μ˜ κ°μ²΄λŠ” 금방 μ ‘κ·Ό λΆˆκ°€λŠ₯ν•œ μƒνƒœ(unreachable)κ°€ λœλ‹€. 즉, 금방 garbageκ°€ λœλ‹€.
  • 였래된 κ°μ²΄μ—μ„œ μ Šμ€ 객체둜의 μ°Έμ‘°λŠ” μ•„μ£Ό 적게 μ‘΄μž¬ν•œλ‹€.

그리고, oracle μ‚¬μ΄νŠΈμ— μžˆλŠ” GC의 기본사항을 보면 λ‹€μŒκ³Ό 같이 μ ν˜€μ Έ μžˆμŠ΅λ‹ˆλ‹€.

JVM의 λͺ¨λ“  개체λ₯Ό ν‘œμ‹œν•˜κ³  μ••μΆ•ν•΄μ•Ό ν•˜λŠ” 것은 λΉ„νš¨μœ¨μ μž…λ‹ˆλ‹€. 더 λ§Žμ€ κ°œμ²΄κ°€ 할당됨에 따라 개체 λͺ©λ‘μ΄ λŠ˜μ–΄λ‚˜κ³  κ°€λΉ„μ§€ μˆ˜μ§‘ μ‹œκ°„μ΄ 점점 더 κΈΈμ–΄μ§‘λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μ‘μš© ν”„λ‘œκ·Έλž¨μ— λŒ€ν•œ κ²½ν—˜μ  뢄석에 λ”°λ₯΄λ©΄ λŒ€λΆ€λΆ„μ˜ κ°œμ²΄λŠ” 수λͺ…이 μ§§μŠ΅λ‹ˆλ‹€.

μœ„μ˜ μ–΄λ €μš΄ λ‚΄μš©μ„ ν•œ μ€„λ‘œ μš”μ•½ν•˜μžλ©΄, 금방 garbageκ°€ λ˜μ–΄μ„œ GC의 λŒ€μƒμ΄ λ˜λ‹ˆ ν•œ λ²ˆμ— ν•˜λŠ” 것 보닀 μ„ΈλŒ€λ³„λ‘œ λ‚˜λˆ„μ–΄μ„œ GCλ₯Ό μˆ˜ν–‰ν•˜λŠ” 것이 더 νš¨μœ¨μ μ΄λΌλŠ” 말 μž…λ‹ˆλ‹€.


이번 κΈ€μ—μ„œ GC의 μ’…λ₯˜κΉŒμ§€ λ‹€λ£° μƒκ°μ΄μ—ˆμ§€λ§Œ, 생각보닀 글이 κΈΈμ–΄μ Έ GC의 μ’…λ₯˜μ— λŒ€ν•΄μ„œλŠ” λ‹€μŒ κΈ€μ—μ„œ λ‹€λ£¨κ² μŠ΅λ‹ˆλ‹€.

λ§ˆμ§€λ§‰ ν•œλ§ˆλ””..

κ³΅μ‹λ¬Έμ„œλ₯Ό λ³΄λŠ” 법을 μ•„μ£Ό μ‚¬μ•„μ•„μ•Œμ§ μ•Œ 것 κ°™μŠ΅λ‹ˆλ‹€. λ‹€λ₯Έ λΈ”λ‘œκ·Έλ₯Ό μ°Έκ³ ν•˜λŠ” 것 보닀 κ³΅μ‹λ¬Έμ„œλ₯Ό 보고 μ΄ν•΄ν•˜λŠ” 것이 더 μ‰¬μ› μŠ΅λ‹ˆλ‹€. λ¬Όλ‘  유튜브λ₯Ό 보며 이해λ₯Ό λ„μ™”μŠ΅λ‹ˆλ‹€ γ…Žγ…Ž


References