Develop

C#) Grbage Collector

proggg 2024. 4. 22. 16:21

C#μ—μ„œμ˜ 가비지 컬렉터 λ™μž‘ 원리와 λ©”λͺ¨λ¦¬ 관리

 

C# λ©”λͺ¨λ¦¬ ꡬ쑰: νž™(Heap)κ³Ό μŠ€νƒ(Stack)

C#μ—μ„œ λ©”λͺ¨λ¦¬ κ΄€λ¦¬λŠ” 크게 두 가지 μ˜μ—­μœΌλ‘œ λ‚˜λ‰©λ‹ˆλ‹€: μŠ€νƒ(Stack)κ³Ό νž™(Heap)μž…λ‹ˆλ‹€. 이 두 μ˜μ—­μ€ μ„œλ‘œ λ‹€λ₯Έ λ°©μ‹μœΌλ‘œ λ©”λͺ¨λ¦¬λ₯Ό κ΄€λ¦¬ν•˜λ©°, 가비지 μ»¬λ ‰ν„°λŠ” 주둜 νž™(Heap) λ©”λͺ¨λ¦¬λ₯Ό κ΄€λ¦¬ν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€.

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

μŠ€νƒμ€ ν•¨μˆ˜ 호좜 μ‹œ 지역 λ³€μˆ˜μ™€ 맀개 λ³€μˆ˜λ₯Ό μ €μž₯ν•˜λŠ” λ©”λͺ¨λ¦¬ κ³΅κ°„μž…λ‹ˆλ‹€. μŠ€νƒμ— μ €μž₯λ˜λŠ” λ°μ΄ν„°λŠ” 컴파일 νƒ€μž„μ— 크기가 κ²°μ •λ˜λŠ” κ°’ νƒ€μž…(Value Type)μž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ int, float, bool, struct와 같은 κ°’ νƒ€μž…μ€ λͺ¨λ‘ μŠ€νƒμ— μ €μž₯λ©λ‹ˆλ‹€.

  • LIFO(Last In, First Out) ꡬ쑰둜, λ§ˆμ§€λ§‰μ— λ“€μ–΄κ°„ 데이터가 κ°€μž₯ λ¨Όμ € λ‚˜μ˜΅λ‹ˆλ‹€.
  • ν•¨μˆ˜κ°€ 호좜될 λ•Œ μŠ€νƒμ— λ©”λͺ¨λ¦¬κ°€ ν• λ‹Ήλ˜κ³ , ν•¨μˆ˜κ°€ μ’…λ£Œλ˜λ©΄ ν•΄λ‹Ή λ©”λͺ¨λ¦¬κ°€ μžλ™μœΌλ‘œ ν•΄μ œλ©λ‹ˆλ‹€.
  • λ©”λͺ¨λ¦¬ 관리가 맀우 λΉ λ₯΄κ³  κ°„λ‹¨ν•˜μ§€λ§Œ, ν•œμ •λœ 크기λ₯Ό 가지며, λ³΅μž‘ν•œ 객체λ₯Ό μ €μž₯ν•˜κΈ°μ—λŠ” μ ν•©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

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

νž™μ€ 주둜 μ°Έμ‘° νƒ€μž…(Reference Type) 데이터λ₯Ό μ €μž₯ν•˜λŠ” μ˜μ—­μž…λ‹ˆλ‹€. 클래슀 객체, λ°°μ—΄, 델리게이트, λ¬Έμžμ—΄ 같은 μ°Έμ‘° νƒ€μž…μ€ νž™μ— μ €μž₯되며, 이듀에 λŒ€ν•œ μ°Έμ‘°(포인터)κ°€ μŠ€νƒμ— μ €μž₯λ©λ‹ˆλ‹€.

  • νž™μ€ 동적 λ©”λͺ¨λ¦¬ 할당이 μΌμ–΄λ‚˜λŠ” 곳으둜, 크기와 수λͺ…이 μœ λ™μ μΈ 데이터λ₯Ό μ €μž₯ν•©λ‹ˆλ‹€.
  • μ°Έμ‘° νƒ€μž…μ΄ μƒμ„±λ˜λ©΄ νž™μ— λ©”λͺ¨λ¦¬κ°€ ν• λ‹Ήλ˜κ³ , ν•΄λ‹Ή λ©”λͺ¨λ¦¬μ˜ μ£Όμ†Œκ°€ μŠ€νƒμ— μ €μž₯λ©λ‹ˆλ‹€. 이 μ£Όμ†Œλ₯Ό 톡해 μ°Έμ‘° νƒ€μž… 객체에 μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • νž™μ— μ €μž₯된 κ°μ²΄λŠ” λͺ…μ‹œμ μœΌλ‘œ ν•΄μ œλ˜μ§€ μ•ŠμœΌλ©°, μ‚¬μš©λ˜μ§€ μ•Šκ²Œ 되면 가비지 컬렉터가 이λ₯Ό μžλ™μœΌλ‘œ μ •λ¦¬ν•©λ‹ˆλ‹€.

가비지 컬렉터(Garbage Collector)의 λ™μž‘ 원리

가비지 μ»¬λ ‰ν„°λŠ” νž™ μ˜μ—­μ—μ„œ μ‚¬μš©λ˜μ§€ μ•ŠλŠ” 객체λ₯Ό μ°Ύμ•„ μžλ™μœΌλ‘œ λ©”λͺ¨λ¦¬λ₯Ό νšŒμˆ˜ν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€. μ΄λŠ” κ°œλ°œμžκ°€ 직접 λ©”λͺ¨λ¦¬ ν•΄μ œλ₯Ό μ‹ κ²½ μ“Έ ν•„μš” 없이, ν”„λ‘œκ·Έλž¨μ΄ μ’…λ£Œλ˜κ±°λ‚˜ λ©”λͺ¨λ¦¬ λΆ€μ‘± μƒν™©μ—μ„œ λ©”λͺ¨λ¦¬κ°€ λˆ„μ λ˜λŠ” 것을 방지해 μ€λ‹ˆλ‹€.

μ„ΈλŒ€λ³„(Generational) 가비지 μ»¬λ ‰μ…˜

C#의 가비지 μ»¬λ ‰ν„°λŠ” μ„ΈλŒ€(Generation) κ°œλ…μ„ λ„μž…ν•˜μ—¬, 객체의 수λͺ… 주기에 따라 λ‹€λ₯Έ λ°©μ‹μœΌλ‘œ λ©”λͺ¨λ¦¬λ₯Ό κ΄€λ¦¬ν•©λ‹ˆλ‹€. 가비지 μ»¬λ ‰ν„°λŠ” μ„Έ 가지 μ„ΈλŒ€λ‘œ λ‚˜λˆ„μ–΄ 객체λ₯Ό κ΄€λ¦¬ν•©λ‹ˆλ‹€.

  • μ„ΈλŒ€ 0 (Generation 0): μƒˆλ‘­κ²Œ ν• λ‹Ήλœ 객체듀이 μ €μž₯λ©λ‹ˆλ‹€. μ„ΈλŒ€ 0은 κ°€μž₯ λΉ λ₯΄κ²Œ μˆ˜μ§‘λ˜λ©°, 수λͺ…이 짧은 객체듀이 주둜 이 μ˜μ—­μ— ν• λ‹Ήλ©λ‹ˆλ‹€. μΌμ‹œμ μœΌλ‘œ μ‚¬μš©λ˜λŠ” λ§Žμ€ 객체듀은 μ„ΈλŒ€ 0μ—μ„œ λ©”λͺ¨λ¦¬κ°€ νšŒμˆ˜λ©λ‹ˆλ‹€.
  • μ„ΈλŒ€ 1 (Generation 1): μ„ΈλŒ€ 0의 가비지 μ»¬λ ‰μ…˜μ—μ„œ 살아남은 객체듀이 이곳으둜 μ΄λ™ν•©λ‹ˆλ‹€. 보톡 쀑간 수λͺ…μ˜ 객체듀이 여기에 μ†ν•©λ‹ˆλ‹€.
  • μ„ΈλŒ€ 2 (Generation 2): μ—¬λŸ¬ 번의 가비지 μ»¬λ ‰μ…˜μ—μ„œ 살아남은 μž₯κΈ° 객체듀이 이곳에 μžˆμŠ΅λ‹ˆλ‹€. κΈ΄ 수λͺ…을 가진 객체듀, 예λ₯Ό λ“€μ–΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ „λ°˜μ— 걸쳐 μ‚¬μš©λ˜λŠ” κ°μ²΄λŠ” μ„ΈλŒ€ 2에 머무λ₯΄κ²Œ λ©λ‹ˆλ‹€.

가비지 μ»¬λ ‰μ…˜ κ³Όμ •

  1. 루트(Root) 탐색: 가비지 μ»¬λ ‰ν„°λŠ” λ¨Όμ € ν”„λ‘œκ·Έλž¨μ˜ 루트 객체, 즉 μŠ€νƒ, CPU λ ˆμ§€μŠ€ν„°, 정적 λ³€μˆ˜ λ“±μ˜ 루트 μ°Έμ‘°λ₯Ό μ°Ύμ•„λƒ…λ‹ˆλ‹€. 이 루트 객체듀은 μ‚΄μ•„ μžˆλŠ” 객체듀을 μ°Έμ‘°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  2. 객체 κ·Έλž˜ν”„ 좔적: 루트 μ°Έμ‘°μ—μ„œ μ—°κ²°λœ λͺ¨λ“  객체듀을 νƒμƒ‰ν•˜μ—¬ μ‚¬μš© 쀑인 객체λ₯Ό μΆ”μ ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ 객체듀은 가비지 μ»¬λ ‰μ…˜ λŒ€μƒμ—μ„œ μ œμ™Έλ©λ‹ˆλ‹€.
  3. μ‚¬μš©λ˜μ§€ μ•ŠλŠ” 객체(가비지) 식별: 루트 μ°Έμ‘°μ—μ„œ 도달할 수 μ—†λŠ” κ°μ²΄λŠ” 더 이상 μ‚¬μš©λ˜μ§€ μ•ŠλŠ” 객체둜 κ°„μ£Όλ˜λ©°, κ°€λΉ„μ§€λ‘œ μ‹λ³„λ©λ‹ˆλ‹€.
  4. λ©”λͺ¨λ¦¬ 회수: κ°€λΉ„μ§€λ‘œ μ‹λ³„λœ κ°μ²΄λ“€μ˜ λ©”λͺ¨λ¦¬λŠ” ν•΄μ œλ˜μ–΄ λ‹€μ‹œ μ‚¬μš© κ°€λŠ₯ν•œ μƒνƒœλ‘œ λ°˜ν™˜λ©λ‹ˆλ‹€. λ©”λͺ¨λ¦¬κ°€ ν•΄μ œλ˜λŠ” κ³Όμ •μ—μ„œ **μ’…λ£Œμž(Finalizer)**κ°€ 호좜될 수 있으며, 이 μ’…λ£ŒμžλŠ” 객체가 ν•΄μ œλ˜κΈ° 전에 νŠΉλ³„ν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ„ΈλŒ€λ³„ μˆ˜μ§‘ μ „λž΅

  • μ„ΈλŒ€ 0 μˆ˜μ§‘: 가비지 μ»¬λ ‰ν„°λŠ” μ„ΈλŒ€ 0을 자주 μˆ˜μ§‘ν•©λ‹ˆλ‹€. μ΄λŠ” 짧은 수λͺ…μ˜ 객체듀이 이 μ˜μ—­μ— μ§‘μ€‘λ˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. λŒ€λΆ€λΆ„μ˜ κ°μ²΄λŠ” μ„ΈλŒ€ 0μ—μ„œ μƒμ„±λ˜κ³ , 가비지 μ»¬λ ‰μ…˜μ„ 톡해 κ³§λ°”λ‘œ λ©”λͺ¨λ¦¬μ—μ„œ ν•΄μ œλ©λ‹ˆλ‹€.
  • μ„ΈλŒ€ 1 및 2 μˆ˜μ§‘: μ„ΈλŒ€ 0μ—μ„œ 가비지 μ»¬λ ‰μ…˜μ΄ λ°˜λ³΅λ˜λ©΄μ„œ 살아남은 κ°μ²΄λŠ” μ„ΈλŒ€ 1, κ·Έ ν›„μ—λŠ” μ„ΈλŒ€ 2둜 μ΄λ™ν•©λ‹ˆλ‹€. μ„ΈλŒ€ 2λŠ” κ°€μž₯ 였래된 객체듀이 λ¨Έλ¬΄λŠ” μ˜μ—­μ΄λ―€λ‘œ, μ„ΈλŒ€ 0에 λΉ„ν•΄ 덜 자주 μˆ˜μ§‘λ©λ‹ˆλ‹€.

μ΄λŸ¬ν•œ μ„ΈλŒ€λ³„ μˆ˜μ§‘ μ „λž΅μ„ 톡해, 가비지 μ»¬λ ‰ν„°λŠ” 자주 μ‚¬μš©λ˜λŠ” κ°μ²΄λŠ” λΉ λ₯΄κ²Œ μˆ˜μ§‘ν•˜λ©΄μ„œλ„ μž₯기적으둜 μ‚¬μš©λ˜λŠ” κ°μ²΄λŠ” μˆ˜μ§‘ λΉˆλ„λ₯Ό μ€„μž„μœΌλ‘œμ¨ μ„±λŠ₯을 μ΅œμ ν™”ν•©λ‹ˆλ‹€.

가비지 μ»¬λ ‰ν„°μ˜ λ™μž‘ μ‹œμ 

가비지 μ»¬λ ‰μ…˜μ€ λ‹€μŒκ³Ό 같은 μ‹œμ μ— μ‹€ν–‰λ©λ‹ˆλ‹€.

  • λ©”λͺ¨λ¦¬ λΆ€μ‘±: νž™ μ˜μ—­μ— 더 이상 객체λ₯Ό μ €μž₯ν•  곡간이 λΆ€μ‘±ν•  λ•Œ.
  • 가비지 μ»¬λ ‰μ…˜μ΄ ν•„μš”ν•˜λ‹€κ³  νŒλ‹¨λ  λ•Œ: μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ λ©”λͺ¨λ¦¬λ₯Ό μ§€λ‚˜μΉ˜κ²Œ 많이 μ‚¬μš©ν•˜κ³  μžˆμ„ λ•Œ.
  • λͺ…μ‹œμ μΈ 호좜: κ°œλ°œμžκ°€ GC.Collect()λ₯Ό ν˜ΈμΆœν•˜μ—¬ 가비지 μ»¬λ ‰μ…˜μ„ κ°•μ œλ‘œ μ‹€ν–‰ν•  λ•Œ.

가비지 μ»¬λ ‰ν„°λŠ” 졜적의 μ„±λŠ₯을 μœ„ν•΄ λΉ„λ™κΈ°λ‘œ μ‹€ν–‰λ©λ‹ˆλ‹€. 즉, ν”„λ‘œκ·Έλž¨μ˜ μ‹€ν–‰κ³Ό λ³„λ„λ‘œ 가비지 μ»¬λ ‰μ…˜μ΄ μˆ˜ν–‰λ˜μ–΄, λ©”λͺ¨λ¦¬ 관리λ₯Ό μœ„ν•΄ ν”„λ‘œκ·Έλž¨μ˜ μ„±λŠ₯에 직접적인 영ν–₯을 주지 μ•Šλ„λ‘ ν•©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 가비지 μ»¬λ ‰μ…˜μ΄ λ°œμƒν•  λ•ŒλŠ” μž μ‹œ μ‹€ν–‰ 쀑인 ν”„λ‘œκ·Έλž¨μ˜ λͺ¨λ“  μŠ€λ ˆλ“œλ₯Ό λ©ˆμΆ”κ³  λ©”λͺ¨λ¦¬ 정리λ₯Ό μˆ˜ν–‰ν•˜κΈ° λ•Œλ¬Έμ—, μ„±λŠ₯이 μ€‘μš”ν•œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œλŠ” 가비지 μ»¬λ ‰μ…˜μ˜ λ°œμƒ μ‹œμ μ„ 잘 관리해야 ν•©λ‹ˆλ‹€.

νž™μ˜ μ„ΈλΆ€ ꡬ쑰

C#의 νž™ λ©”λͺ¨λ¦¬λŠ” λ‹¨μˆœνžˆ ν•˜λ‚˜μ˜ κ³΅κ°„μœΌλ‘œ κ΅¬μ„±λ˜μ§€ μ•ŠμœΌλ©°, **큰 객체 νž™(LOH, Large Object Heap)**κ³Ό **μ†Œν˜• 객체 νž™(SOH, Small Object Heap)**으둜 λ‚˜λ‰©λ‹ˆλ‹€.

  • μ†Œν˜• 객체 νž™(Small Object Heap, SOH): 크기가 μž‘κ³  자주 μ‚¬μš©λ˜λŠ” 객체듀이 μ €μž₯λ©λ‹ˆλ‹€. 일반적으둜 크기가 85,000λ°”μ΄νŠΈ 미만인 κ°μ²΄λŠ” μ†Œν˜• 객체 νž™μ— ν• λ‹Ήλ©λ‹ˆλ‹€.
  • 큰 객체 νž™(Large Object Heap, LOH): 크기가 큰 객체(85,000λ°”μ΄νŠΈ 이상)κ°€ ν• λ‹Ήλ˜λŠ” νž™ μ˜μ—­μž…λ‹ˆλ‹€. 큰 κ°μ²΄λŠ” μ†Œν˜• 객체와 달리 가비지 μ»¬λ ‰μ…˜μ˜ μ„±λŠ₯에 더 큰 영ν–₯을 미치기 λ•Œλ¬Έμ—, LOHλŠ” 가비지 컬렉터가 더 μ‹ μ€‘ν•˜κ²Œ κ΄€λ¦¬ν•©λ‹ˆλ‹€.

LOHλŠ” μ„ΈλŒ€λ³„ 관리가 μ μš©λ˜μ§€ μ•Šκ³ , μˆ˜μ§‘μ΄ λ°œμƒν•  λ•Œλ§ˆλ‹€ 주기적으둜 μ •λ¦¬λ©λ‹ˆλ‹€. μ΄λŠ” 큰 객체의 μˆ˜μ§‘ λΉ„μš©μ΄ 더 크기 λ•Œλ¬Έμ— μ„±λŠ₯에 λ―ΈμΉ˜λŠ” 영ν–₯을 μ΅œμ†Œν™”ν•˜κΈ° μœ„ν•œ λ°©λ²•μž…λ‹ˆλ‹€.

κ²°λ‘ 

C#의 가비지 μ»¬λ ‰ν„°λŠ” νž™ λ©”λͺ¨λ¦¬μ—μ„œ μ‚¬μš©λ˜μ§€ μ•ŠλŠ” 객체λ₯Ό μžλ™μœΌλ‘œ νšŒμˆ˜ν•˜μ—¬ λ©”λͺ¨λ¦¬ λˆ„μˆ˜λ₯Ό λ°©μ§€ν•˜λŠ” μ€‘μš”ν•œ 역할을 ν•©λ‹ˆλ‹€. μŠ€νƒκ³Ό νž™μ˜ ꡬ뢄, μ„ΈλŒ€λ³„ 가비지 μ»¬λ ‰μ…˜ μ „λž΅, 그리고 νŠΉμ • μ‹œμ μ—μ„œ μˆ˜λ™μœΌλ‘œ 가비지 μ»¬λ ‰μ…˜μ„ μ œμ–΄ν•˜λŠ” 방법을 μ΄ν•΄ν•˜λ©΄, 더 λ‚˜μ€ λ©”λͺ¨λ¦¬ 관리와 μ„±λŠ₯ μ΅œμ ν™”λ₯Ό 이룰 수 μžˆμŠ΅λ‹ˆλ‹€.

가비지 μ»¬λ ‰ν„°λŠ” μžλ™μœΌλ‘œ λ™μž‘ν•˜μ§€λ§Œ, ν”„λ‘œμ νŠΈμ˜ 성격에 따라 이λ₯Ό 적절히 μ œμ–΄ν•˜κ±°λ‚˜ μ»€μŠ€ν„°λ§ˆμ΄μ§•ν•  수 μžˆλŠ” λŠ₯λ ₯은 C# κ°œλ°œμžλ‘œμ„œ μ€‘μš”ν•œ μ—­λŸ‰μž…λ‹ˆλ‹€.