What is Garbage Collection in .NET Framework?

ู„ู…ุง ุฃูŠ ุงุจู„ูƒูŠุดู† dot net ุจูŠุดุชุบู„ุŒ ุจูŠุชุนู…ู„ objects ูƒุชูŠุฑ ุฌุฏู‹ุง ููŠ ุงู„ู…ูŠู…ูˆุฑูŠ. ูˆููŠ ูˆู‚ุช ู…ุนูŠู†ุŒ ู…ู…ูƒู† ุงู„ุชุทุจูŠู‚ ุจุชุงุนูƒ ู…ูŠูƒูˆู†ุด ุจูŠุณุชุฎุฏู… ุจุนุถ ุงู„ู€ objects ุฏูŠ. ู‡ู†ุง ุจูŠุฌูŠ ุฏูˆุฑ ุงู„ู€ Garbage Collector ููŠ .NET FrameworkุŒ ูˆู‡ูˆ ุนุจุงุฑุฉ ุนู† ุฑูˆุชูŠู† ุตุบูŠุฑุŒ ุฃูˆ ู†ู‚ุฏุฑ ู†ู‚ูˆู„ ุฅู†ู‡ Background Process Thread ุจูŠุดุชุบู„ ุจุดูƒู„ ุฏูˆุฑูŠ ุนุดุงู† ูŠุญุงูˆู„ ูŠุญุฏุฏ ุฅูŠู‡ ู‡ูŠ ุงู„ู€ objects ุงู„ู„ูŠ ู…ุด ู…ุณุชุฎุฏู…ุฉ ุญุงู„ูŠู‹ุง ู…ู† ุฎู„ุงู„ ุงู„ุชุทุจูŠู‚ุŒ ูˆุจุนุฏูŠู† ุจูŠุจุฏุฃ ูŠุญุฑุฑ ุงู„ุฐุงูƒุฑุฉ ุงู„ุฎุงุตุฉ ุจุงู„ู€ objects ุฏูŠ ูˆูŠูุถูŠู‡ุง.

ุฅุฐู†ุŒ ุงู„ู€ Garbage Collector ู‡ูˆ ู…ูŠุฒุฉ ู…ู‡ู…ุฉ ุจูŠู‚ุฏู…ู‡ุง ุงู„ู€ CLR ุนุดุงู† ุชุณุงุนุฏู†ุง ู†ู†ุถู ุฃูˆ ู†ุฏู…ุฑ ุงู„ู€ managed objects ุบูŠุฑ ุงู„ู…ุณุชุฎุฏู…ุฉ. ุนู…ู„ูŠุฉ ุชู†ุธูŠู ุงู„ู€ objects ุฏูŠ ุจุชุฑุฌุนู„ู†ุง ุงู„ู…ุณุงุญุฉ ุงู„ู„ูŠ ูƒุงู†ุช ูˆุงุฎุฏู‡ุง ููŠ ุงู„ุฐุงูƒุฑุฉ ุนุดุงู† ู†ู‚ุฏุฑ ู†ุณุชุฎุฏู…ู‡ุง ุชุงู†ูŠ.

ุงู„ู€ Garbage Collection (GC) ููŠ .NET Framework ุจูŠุนุชุจุฑ ู†ุธุงู… ุฅุฏุงุฑุฉ ุงู„ู…ูŠู…ูˆุฑูŠ ุชู„ู‚ุงุฆูŠ (Automatic Memory Management)ุจูŠุณุงุนุฏูƒ ุชู‡ู†ุฏู„ ุญูˆุงุฑ ุงู„ู…ูŠู…ูˆุฑูŠ ููŠ ุชุทุจูŠู‚ุงุชูƒ. ููŠ ู„ุบุงุช .NETุŒ ู„ู…ุง ุจู†ุนู…ู„ object ุฌุฏูŠุฏ ุจุงุณุชุฎุฏุงู… ูƒู„ู…ุฉ newุŒ ุจูŠุชู… ุชุฎุตูŠุต ู…ุณุงุญุฉ ู„ูŠู‡ ููŠ ุงู„ู…ูŠู…ูˆุฑูŠ ุชู„ู‚ุงุฆูŠู‹ุง ุนู„ู‰ ุงู„ู€ managed heap. ูุจุงู„ุชุงู„ูŠุŒ ุฅู†ุช ู…ุด ู…ุญุชุงุฌ ุชุฎุตุต ุฃูˆ ุชุญุฑุฑ ุงู„ุฐุงูƒุฑุฉ ุจู†ูุณูƒ ุจุดูƒู„ ูŠุฏูˆูŠ ุฒูŠ ู…ุง ุจุชุนู…ู„ ููŠ ู„ุบุงุช ุชุงู†ูŠุฉ ุฒูŠ C ุฃูˆ C++.

ู…ู„ุญูˆุธุฉ: ุงู„ู€ Garbage Collector ุจูŠุฏู…ุฑ ุจุณ ุงู„ู€ managed objects ุบูŠุฑ ุงู„ู…ุณุชุฎุฏู…ุฉุŒ ู„ูƒู†ู‡ ู…ุด ุจูŠู†ุถู ุงู„ู€ unmanaged objects.

Managed and Unmanaged Objects in .NET Framework

ุฎู„ูŠู†ุง ู†ูู‡ู… ุฅูŠู‡ ู‡ู…ุง ุงู„ู€ Managed objects ูˆุงู„ู€ Unmanaged objects. ู„ู…ุง ุจู†ุนู…ู„ ุฃูŠ ู…ู„ู EXE (ุณูˆุงุก ูƒุงู† Console Application ุฃูˆ Windows Application) ุฃูˆ Web Application (ุฒูŠ ASP.NET MVC ุฃูˆ Web API)ุŒ ุงู„ุชุทุจูŠู‚ุงุช ุฏูŠ ุจุชุดุชุบู„ ุจุงู„ูƒุงู…ู„ ุชุญุช ุณูŠุทุฑุฉ ูˆุชุญูƒู… ุงู„ู€ CLR (Common Language Runtime). ุฏู‡ ู…ุนู†ุงู‡ ุฅู† ู„ูˆ ุชุทุจูŠู‚ุงุชูƒ ููŠู‡ุง objects ุบูŠุฑ ู…ุณุชุฎุฏู…ุฉุŒ ุงู„ู€ CLR ู‡ูŠู†ุถูู‡ุง ุชู„ู‚ุงุฆูŠู‹ุง ุจุงุณุชุฎุฏุงู… ุงู„ู€ Garbage Collector.

ู„ู†ูุชุฑุถ ุฅู†ูƒ ุงุณุชุฎุฏู…ุช ู…ู„ู EXE ู…ู† ุทุฑู ุชุงู„ุช (third-party) ููŠ ุชุทุจูŠู‚ูƒุŒ ุฒูŠ ุจุฑู†ุงู…ุฌ SkypeุŒ PowerPointุŒ ุฃูˆ Microsoft Excel. ุงู„ู€ EXEs ุฏูŠ ู…ุด ู…ุนู…ูˆู„ุฉ ุจุชูƒู†ูˆู„ูˆุฌูŠุง dot netุŒ ุฏูŠ ู…ุนู…ูˆู„ุฉ ุจู„ุบุงุช ุจุฑู…ุฌุฉ ุชุงู†ูŠุฉ ุฒูŠ CุŒ C++ุŒ ุฃูˆ Java.

ู„ู…ุง ุจุชุณุชุฎุฏู… ุงู„ู€ EXEs ุฏูŠ ููŠ ุชุทุจูŠู‚ูƒุŒ ู‡ูŠ ู…ุด ุจุชุดุชุบู„ ุชุญุช ุฅุฏุงุฑุฉ ุงู„ู€ CLR. ุญุชู‰ ู„ูˆ ุดุบู„ุชู‡ุง ุฌูˆู‡ ุชุทุจูŠู‚ุงุช dot netุŒ ู‡ูŠ ู‡ุชุดุชุบู„ ุชุญุช ุจูŠุฆุชู‡ุง ุงู„ุฎุงุตุฉ ุจูŠู‡ุง. ูŠุนู†ูŠ ู…ุซู„ุงู‹ุŒ ู„ูˆ ุงู„ู€ EXE ุฏู‡ ู…ุนู…ูˆู„ ุจู€ C ุฃูˆ C++ุŒ ู‡ูŠุดุชุบู„ ุชุญุช ุงู„ู€ C ุฃูˆ C++ Runtime Environment.

  • ุงู„ู€ Managed Code: ู‡ูˆ ุงู„ูƒูˆุฏ ุงู„ู„ูŠ ุจูŠุดุชุบู„ ุชุญุช ุชุญูƒู… ูƒุงู…ู„ ู…ู† ุงู„ู€ CLR ููŠ .NET Framework. ุงู„ู€ CLR ุจูŠูˆูุฑ ูƒู„ ุงู„ู…ู…ูŠุฒุงุช ุจุชุงุนุชู‡ ู„ู„ู€ managed code ุฒูŠ ุงู„ู€ Language InteroperabilityุŒ ุงู„ู€ Automatic Memory ManagementุŒ ุงู„ู€ Exception HandlingุŒ ูˆุงู„ู€ Code Access Security.
  • ุงู„ู€ Unmanaged Code: ู‡ูˆ ุงู„ูƒูˆุฏ ุงู„ู„ูŠ ู…ุด ุจูŠุดุชุบู„ ุชุญุช ุชุญูƒู… ุงู„ู€ CLRุŒ ุฒูŠ ุจุฑุงู…ุฌ Skype ูˆ Excel. ูˆุจุงู„ุชุงู„ูŠุŒ ุงู„ู€ CLR ู…ุด ุจูŠูˆูุฑ ุฃูŠ ู…ูŠุฒุฉ ู…ู† ู…ู…ูŠุฒุงุชู‡ ู„ู„ูƒูˆุฏ ุฏู‡.

Managed Objects

  • ู‡ูŠ ุนุจุงุฑุฉ ุนู† objects ุจุชุชุนู…ู„ ุนู„ู‰ ุงู„ู€ managed heap ูˆุจูŠุชุญูƒู… ููŠู‡ุง ุงู„ู€ Garbage Collector (GC) ุจุชุงุน ุจูŠุฆุฉ .NET.
  • ุงู„ู€ GC ู‡ูˆ ุงู„ู…ุณุคูˆู„ ุนู† ุฅุฏุงุฑุฉ Memory ุจุชุงุนุชู‡ุง ุชู„ู‚ุงุฆูŠู‹ุง.
  • ุฃู…ุซู„ุฉ ุนู„ูŠู‡ุง: ุฃูŠ instance ู…ู† class ุฃูˆ struct ุจุชุนู…ู„ู‡ ุจุงุณุชุฎุฏุงู… ูƒู„ู…ุฉ new ููŠ C# ุฃูˆ VB.NETุŒ ุฃูˆ ุงู„ู€ objects ุงู„ุฃุณุงุณูŠุฉ ุฒูŠ ุงู„ู€ arrays ูˆุงู„ู€ strings.

Unmanaged Objects

  • ู‡ูŠ ุนุจุงุฑุฉ ุนู† objects ุงู„ุฐุงูƒุฑุฉ ุจุชุงุนุชู‡ุง ู…ุด ุจุชุฏุงุฑ ุจูˆุงุณุทุฉ ุงู„ู€ GC.
  • ุฏูŠ ููŠ ุงู„ุนุงุฏุฉ ุจุชูƒูˆู† objects ุจุชุชุนู…ู„ ุจูƒูˆุฏ ุฃุตู„ูŠ (native code)ุŒ ุฒูŠ ุงุณุชุฏุนุงุกุงุช ุงู„ู€ Windows API ุฃูˆ ุนู† ุทุฑูŠู‚ ุงุณุชุฎุฏุงู… ู„ุบุงุช ุฒูŠ C ุฃูˆ C++.
  • ุงู„ู…ุจุฑู…ุฌ ู‡ู†ุง ู‡ูˆ ุงู„ู…ุณุคูˆู„ ุนู† ุญูˆุงุฑ ุงู„ู…ูŠู…ูˆุฑูŠ ุจุชุงุนุชู‡ุง ุจู†ูุณู‡ ุจุงุณุชุฎุฏุงู… APIs ู…ุนูŠู†ุฉ ุฒูŠ malloc ูˆ free ููŠ ู„ุบุฉ C ุฃูˆ new ูˆ delete ููŠ ู„ุบุฉ C++.
  • ุฃู…ุซู„ุฉ ุนู„ูŠู‡ุง: ุงู„ู€ file handlesุŒ ุงุชุตุงู„ุงุช DBุŒ ูˆุงู„ู€ COM objects.

Garbage Collection Memory Generations

ุฎู„ูŠู†ุง ู†ูู‡ู… ุฅูŠู‡ ู‡ูŠ ุฃุฌูŠุงู„ ุงู„ู€ Garbage Collector ูˆุฅุฒุงูŠ ุจุชุฃุซุฑ ุนู„ู‰ ุงู„ุฃุฏุงุก ุจุชุงุนู‡. ุงู„ู€ GC ู…ุชู‚ุณู… ู„ุชู„ุงุช ุฃุฌูŠุงู„: ุงู„ู€ Generation 0ุŒ ุงู„ู€ Generation 1ุŒ ูˆุงู„ู€ Generation 2.

Understanding Generation 0, 1, and 2

ู„ู†ูุชุฑุถ ุฅู† ุนู†ุฏูƒ ุชุทุจูŠู‚ ุจุณูŠุท ุงุณู…ู‡ App1. ุจู…ุฌุฑุฏ ู…ุง ุงู„ุชุทุจูŠู‚ ุฏู‡ ูŠุจุฏุฃ ูŠุดุชุบู„ุŒ ุจูŠุนู…ู„ 5 ู…ู† ุงู„ู€ managed objects. ููŠ ุงู„ุนุงุฏูŠุŒ ูƒู„ ู…ุง ูŠุชู… ุฅู†ุดุงุก objects ุฌุฏูŠุฏุฉุŒ ุจุชุชุญุท ููŠ โ€œุฌุฑุฏู„โ€ (Bucket) ุงุณู…ู‡ Generation 0.

graph TD
    subgraph Heap
        subgraph "Generation 0"
            direction LR
            O1(Object1)
            O2(Object2)
            O3(Object3)
            O4(Object4)
            O5(Object5)
        end
    end
    A[New Objects] --> O1

ุฅุญู†ุง ุนุงุฑููŠู† ุฅู† ุงู„ู€ Garbage Collector ุจูŠุดุชุบู„ ุจุงุณุชู…ุฑุงุฑ ููŠ ุงู„ุฎู„ููŠุฉ ุนุดุงู† ูŠุดูŠูƒ ูˆูŠุดูˆู ู„ูˆ ููŠู‡ ุฃูŠ objects ุบูŠุฑ ู…ุณุชุฎุฏู…ุฉ. ู„ู†ูุชุฑุถ ุฅู† ุงู„ุชุทุจูŠู‚ ุจุชุงุนู†ุง ู…ุจู‚ุงุด ู…ุญุชุงุฌ Object1 ูˆ Object2. ุงู„ู€ GC ู‡ูŠุฏู…ุฑู‡ู… ูˆูŠุฑุฌุน ุงู„ู…ุณุงุญุฉ ุจุชุงุนุชู‡ู… ู„ู„ู…ูŠู…ูˆุฑูŠ ู…ู† ุงู„ู€ Generation 0. ู„ูƒู† ู…ู† ู†ุงุญูŠุฉ ุชุงู†ูŠุฉุŒ ุงู„ุชุทุจูŠู‚ ู„ุณู‡ ู…ุญุชุงุฌ ุจุงู‚ูŠ ุงู„ุชู„ุงุชุฉ objects. ุงู„ู€ GC ู…ุด ู‡ูŠู†ุถูู‡ู…ุŒ ูˆุจุฏู„ู‹ุง ู…ู† ูƒุฏู‡ ู‡ูŠู†ู‚ู„ู‡ู… ู„ู„ุฌูŠู„ ุงู„ู„ูŠ ุจุนุฏู‡ ูˆู‡ูˆ ุงู„ู€ Generation 1.

graph TD
    subgraph Heap
        subgraph "Generation 0"
            G0["Empty"]
        end
        subgraph "Generation 1"
            direction LR
            O3(Object3)
            O4(Object4)
            O5(Object5)
        end
    end

    X(๐Ÿ—‘๏ธ Garbage)
    O1[Object1] -- Destroyed --> X
    O2[Object2] -- Destroyed --> X

    subgraph Survivors
        direction LR
        S3(Object3)
        S4(Object4)
        S5(Object5)
    end

    S3 -- Promoted --> O3
    S4 -- Promoted --> O4
    S5 -- Promoted --> O5

ู„ู†ูุชุฑุถ ุฏู„ูˆู‚ุชูŠ ุฅู† ุชุทุจูŠู‚ูƒ ุนู…ู„ ุงุชู†ูŠู† objects ุฌุฏุงุฏ (Object6 ูˆ Object7). ุจู…ุง ุฅู†ู‡ู… objects ู„ุณู‡ ุฌุฏุงุฏุŒ ู‡ูŠุชุญุทูˆุง ู…ุจุงุดุฑุฉ ููŠ ุงู„ู€ Generation 0.

ุฏู„ูˆู‚ุชูŠุŒ ุงู„ู€ GC ู‡ูŠุดุชุบู„ ู…ุฑุฉ ุชุงู†ูŠุฉุŒ ูˆุจูŠุฑูˆุญ ุฃูˆู„ ุญุงุฌุฉ ู„ู„ู€ Generation 0 ูˆูŠุดูˆู ุฅูŠู‡ ุงู„ู€ objects ุงู„ู…ุณุชุฎุฏู…ุฉ. ู„ู†ูุชุฑุถ ุฅู† ุงู„ุงุชู†ูŠู† ุงู„ุฌุฏุงุฏ ู…ุด ู…ุณุชุฎุฏู…ูŠู†ุŒ ูู‡ูŠู…ุณุญู‡ู…. ุจุนุฏูŠู† ูŠุฑูˆุญ ู„ู„ู€ Generation 1 ูˆูŠุดูˆู ุฅูŠู‡ ุงู„ู„ูŠ ู…ุด ู…ุณุชุฎุฏู… ู‡ู†ุงูƒ. ู„ู†ูุชุฑุถ ุฅู† ุงู„ุชุทุจูŠู‚ ู„ุณู‡ ู…ุญุชุงุฌ Object4 ูˆ Object5 ู„ูƒู† ู…ุจู‚ุงุด ู…ุญุชุงุฌ Object3. ุงู„ู€ GC ู‡ูŠุฏู…ุฑ Object3 ูˆูŠู†ู‚ู„ Object4 ูˆ Object5 ู„ู„ุฌูŠู„ ุงู„ุฃุฎูŠุฑ ุงู„ู„ูŠ ู‡ูˆ Generation 2.

Why do we need Generations?

ุงู„ุฃุฌูŠุงู„ ุฏูŠ ุจุชุญุฏุฏ ู…ุฏุฉ ุจู‚ุงุก ุงู„ู€ objects ููŠ ุงู„ุฐุงูƒุฑุฉ. ุทูŠุจ ู„ูŠู‡ ุจู†ุญุชุงุฌ ุงู„ุฃุฌูŠุงู„ ุฏูŠ ุฃุตู„ุงู‹ุŸ

ุงู„ุชุทุจูŠู‚ุงุช ุงู„ูƒุจูŠุฑุฉ ู…ู…ูƒู† ุชุนู…ู„ ุขู„ุงู ู…ู† ุงู„ู€ objects. ู„ูˆ ุงู„ู€ GC ูุถู„ ูŠุดูŠูƒ ุนู„ูŠู‡ู… ูƒู„ู‡ู… ููŠ ูƒู„ ู…ุฑุฉ ุจูŠุดุชุบู„ ููŠู‡ุงุŒ ุงู„ุนู…ู„ูŠุฉ ุฏูŠ ู‡ุชุจู‚ู‰ ู…ุฑู‡ู‚ุฉ ุฌุฏู‹ุง ูˆุจุทูŠุฆุฉ. ุจุญูˆุงุฑ ุงู„ุฃุฌูŠุงู„ ุฏุงุŒ ู„ูˆ ููŠู‡ object ู…ูˆุฌูˆุฏ ููŠ ุงู„ู€ Generation 2ุŒ ุฏู‡ ู…ุนู†ุงู‡ ุฅู† ุงู„ู€ GC ู‡ูŠุฒูˆุฑู‡ ุนุฏุฏ ู…ุฑุงุช ุฃู‚ู„ ุจูƒุชูŠุฑุŒ ู„ุฃู† ุงู„ู€ object ุงู„ู„ูŠ ุจูŠูˆุตู„ ู„ู„ู…ุฑุญู„ุฉ ุฏูŠ ูŠุจู‚ู‰ ู…ุชูˆู‚ุน ุฌุฏู‹ุง ุฅู†ู‡ ู‡ูŠูุถู„ ุนุงูŠุด ููŠ ุงู„ุฐุงูƒุฑุฉ ู„ูุชุฑุฉ ุฃุทูˆู„.

ุจุจุณุงุทุฉุŒ ุชู‚ุณูŠู… ุงู„ุฐุงูƒุฑุฉ ู„ู€ Generations 0, 1, 2 ุจูŠุณุงุนุฏ ุฌุฏู‹ุง ููŠ ุฒูŠุงุฏุฉ ุฃุฏุงุก ูˆุณุฑุนุฉ ุงู„ู€ Garbage Collector. ูƒู„ ู…ุง ูƒุงู†ุช ุฃุบู„ุจ ุงู„ู€ objects ุจุชุฎู„ุต ููŠ ุงู„ู€ Gen 0ุŒ ูƒู„ ู…ุง ูƒุงู† ุงู„ุฃุฏุงุก ุฃุญุณู† ูˆุงู„ุฐุงูƒุฑุฉ ุจุชุณุชุฎุฏู… ุจุดูƒู„ ู…ุซุงู„ูŠ.


How does using a Destructor in a Class end up in a Double Garbage Collector Loop?

ุฒูŠ ู…ุง ูˆุถุญู†ุง ู‚ุจู„ ูƒุฏู‡ุŒ ุงู„ู€ GC ุจูŠู†ุถู ุงู„ู€ managed code ุจุณ. ู„ูˆ ุนู†ุฏูƒ ููŠ ู…ุดุฑูˆุนูƒ unmanaged codeุŒ ู„ุงุฒู… ุชูˆูุฑ ุทุฑูŠู‚ุฉ ุชู†ุถูู‡ ุจูŠู‡ุง ุจู†ูุณูƒ. ูˆุงู„ู…ูƒุงู† ุงู„ู…ู†ุทู‚ูŠ ุงู„ู„ูŠ ู…ู…ูƒู† ุชููƒุฑ ุชุญุท ููŠู‡ ูƒูˆุฏ ุงู„ุชู†ุถูŠู ุฏู‡ ู‡ูˆ ุงู„ู€ destructor ุจุชุงุน ุงู„ู€ class. ู„ูƒู† ู„ู„ุฃุณูุŒ ููŠู‡ ู…ุดูƒู„ุฉ ูƒุจูŠุฑุฉ ุฌุฏู‹ุง ู…ุฑุชุจุทุฉ ุจุงู„ู…ูˆุถูˆุน ุฏู‡.

ู„ู…ุง ุจุชุนุฑู destructor ููŠ ุงู„ู€ class ุจุชุงุนูƒุŒ ุงู„ู€ GC ู‚ุจู„ ู…ุง ูŠุฏู…ุฑ ุงู„ู€ object ุฏู‡ุŒ ุจูŠุฑูˆุญ ูŠุณุฃู„ ุงู„ู€ class: ู‡ู„ ุนู†ุฏูƒ destructorุŸ ู„ูˆ ุงู„ุฅุฌุงุจุฉ ุฃูŠูˆุฉุŒ ุจูŠู†ู‚ู„ ุงู„ู€ object ุฏู‡ ู„ู„ุฌูŠู„ ุงู„ู„ูŠ ุจุนุฏู‡ (next generation bucket). ุจู…ุนู†ู‰ ุชุงู†ูŠุŒ ู…ุด ุจูŠู†ุถูู‡ ููŠ ุณุงุนุชู‡ุงุŒ ุญุชู‰ ู„ูˆ ู‡ูˆ ูุนู„ูŠู‹ุง ู…ุด ู…ุณุชุฎุฏู…. ุงู„ู€ GC ุจูŠุณุชู†ู‰ ุงู„ู€ destructor ูŠุดุชุบู„ ุงู„ุฃูˆู„ุŒ ูˆุจุนุฏูŠู† ููŠ Loop ุงู„ู„ูŠ ุจุนุฏู‡ุง ูŠุฑูˆุญ ูŠู†ุถูู‡. ุจุณุจุจ ุงู„ู„ูุฉ ุฏูŠุŒ ู‡ุชู„ุงู‚ูŠ objects ุฃูƒุชุฑ ุจุชุชุฑุงูƒู… ููŠ ุงู„ู€ Generation 1 ูˆุงู„ู€ Generation 2 ุจุฏู„ ู…ุง ุชุชู†ุถู ููŠ ุงู„ู€ Generation 0ุŒ ูˆุฏู‡ ุจูŠุฃุซุฑ ุจุดูƒู„ ุณู„ุจูŠ ุนู„ู‰ ุงู„ุฃุฏุงุก ูˆุงุณุชู‡ู„ุงูƒ ุงู„ู…ูŠู…ูˆุฑูŠ.

Example using Destructor to Destroy the Unmanaged Resources

ุจุต ุนู„ู‰ ุงู„ูƒูˆุฏ ุฏู‡. ุฏู‡ ู†ูุณ ุงู„ู…ุซุงู„ ุงู„ู„ูŠ ู…ู…ูƒู† ู†ูƒูˆู† ุงุชูƒู„ู…ู†ุง ุนู†ู‡ุŒ ุจุณ ุถูู†ุง destructors ู„ู„ู€ classes ุนุดุงู† ู†ุดูˆู ุงู„ู…ุดูƒู„ุฉ:

using System;
 
namespace GarbageCollectionDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i <= 1000000; i++)
            {
                MyClass1 obj1 = new MyClass1();
                MyClass2 obj2 = new MyClass2();
                MyClass3 obj3 = new MyClass3();
            }
            Console.Read();
        }
    }
 
    public class MyClass1
    {
        ~MyClass1()
        {
            // Clean unmanaged resources here
        }
    }
    
    // Similar for MyClass2 and MyClass3...
}

ู„ูˆ ุดุบู„ุช ุงู„ู…ุซุงู„ ุฏู‡ ูˆุงุณุชุฎุฏู…ุช ุฃุฏุงุฉ ุฒูŠ .NET Memory ProfilerุŒ ู‡ุชู„ุงุญุธ ุจูˆุถูˆุญ ุฅู† ููŠู‡ objects ูƒุชูŠุฑ ุฌุฏู‹ุง ุงุชู†ู‚ู„ุช ูˆุจู‚ุช ููŠ ุงู„ู€ Generation 1 ูˆุงู„ู€ Generation 2. ูˆุฏู‡ ู…ุนู†ุงู‡ ุฅู†ูƒ ู…ุด ุจุชุณุชุบู„ ุงู„ุฐุงูƒุฑุฉ ุจุชุงุนุชูƒ ุจุงู„ุดูƒู„ ุงู„ุตุญ.


How to Overcome the above Problem?

ุงู„ู…ุดูƒู„ุฉ ุงู„ู„ูŠ ุงุชูƒู„ู…ู†ุง ุนู†ู‡ุง ุฏูŠ ุจุชุชุญู„ ุนู† ุทุฑูŠู‚ ุงุณุชุฎุฏุงู… (Pattern) ุงุณู…ู‡ ุงู„ู€ Dispose Pattern. ุนุดุงู† ุชุทุจู‚ Pattern ุฏู‡ุŒ ุงู„ู€ class ุจุชุงุนูƒ ู„ุงุฒู… ูŠุทุจู‚ ุงู„ู€ IDisposable interfaceุŒ ูˆูŠูˆูุฑ (Implementation) ู„ู„ู€ Dispose method. ุฌูˆู‡ ุงู„ู€ Dispose method ุฏูŠุŒ ุจุชูƒุชุจ ุงู„ูƒูˆุฏ ุงู„ุฎุงุต ุจุชู†ุธูŠู ุงู„ู€ unmanaged objectsุŒ ูˆููŠ ุขุฎุฑ ุงู„ู€ method ุจุชุณุชุฏุนูŠ ุฏุงู„ุฉ GC.SuppressFinalize(true). ุงู„ุฏุงู„ุฉ ุฏูŠ ุจุชุฏูŠ ุฃู…ุฑ ูˆุชุจู„ุบ ุงู„ู€ GC ุฅู†ู‡ ูŠุชุฌุงู‡ู„ ุงู„ู€ destructor ุฎุงู„ุต ูˆูŠุฑูˆุญ ูŠู†ุถู ุงู„ู€ objects ุฏูŠ ุนู„ู‰ ุทูˆู„ ู…ู† ุบูŠุฑ ู…ุง ูŠุณุชู†ู‰.

ุจุณ ุฎู„ูŠ ุจุงู„ูƒุŒ ุจุนุฏ ู…ุง ุชุฎู„ุต ุงุณุชุฎุฏุงู… ุงู„ู€ objectุŒ ู„ุงุฒู… ุชุณุชุฏุนูŠ ุงู„ู€ Dispose method ุจู†ูุณูƒ ุฌูˆู‡ ุงู„ูƒูˆุฏ ุนุดุงู† ุชุชุฌู†ุจ ู…ุดูƒู„ุฉ ุงู„ู€ double garbage collector loop.

Example using Dispose Pattern to Destroy the Unmanaged Object in C#

using System;
 
namespace GarbageCollectionDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i <= 1000000; i++)
            {
                MyClass1 obj1 = new MyClass1();
                obj1.Dispose();
                
                MyClass2 obj2 = new MyClass2();
                obj2.Dispose();
                
                MyClass3 obj3 = new MyClass3();
                obj3.Dispose();
            }
            Console.Read();
        }
    }
 
    public class MyClass1 : IDisposable
    {
        #region IDisposable Support
        private bool disposedValue = false; // Detect redundant calls
        
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    // Clean managed objects
                }
                // Clean unmanaged objects
                disposedValue = true;
            }
        }
        
        ~MyClass1()
        {
            Dispose(false);
        }
        
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion
    }
    // Similar implementation for MyClass2 and MyClass3
}

ู„ูˆ ุฌุฑุจุช ุชุดุบู„ ุงู„ู…ุซุงู„ ุฏู‡ ูˆุชุฑุงู‚ุจู‡ ุจุงู„ู€ profilerุŒ ู‡ุชู„ุงุญุธ ุฅู† ู…ุนุธู… ุงู„ู€ objects ู‡ุชูุถู„ ูˆุชุชู†ุถู ููŠ ุงู„ู€ Generation 0ุŒ ูˆุฏู‡ ุทุจุนู‹ุง ุจูŠุญุณู† ู…ู† ุฃุฏุงุก ุชุทุจูŠู‚ูƒ ุจุดูƒู„ ู…ู„ุญูˆุธ.

ุทูŠุจ ู‡ู†ุง ู…ู…ูƒู† ุชุณุฃู„: ู„ูŠู‡ ุงู„ู€ destructor ู„ุณู‡ ู…ูˆุฌูˆุฏ ููŠ ุงู„ูƒูˆุฏุŸ ุงู„ุณุจุจ ู‡ูˆ ุฅู†ู‡ ุจูŠูƒูˆู† ู…ูˆุฌูˆุฏ ูƒู†ูˆุน ู…ู† ุฃู†ูˆุงุน ุงู„ุถู…ุงู† (Safety net). ู„ูˆ ุฃู†ุช ูƒู€ Developer ู†ุณูŠุช ุชู†ุงุฏูŠ ุงู„ู€ Dispose method ุจุฅูŠุฏูƒุŒ ุงู„ู€ destructor ู‡ูŠุดุชุบู„ ููŠ ุงู„ุขุฎุฑ ูˆูŠู†ุถู ุงู„ู€ objectุŒ ูˆุฏู‡ ุจูŠุญู…ูŠูƒ ู…ู† ุฅู† ูŠุญุตู„ (Memory Leak).


Notes

Correction (ุชุตุญูŠุญ ูู†ูŠ)

  • ุฏุงู„ุฉ GC.SuppressFinalize: ูˆุงุญู†ุง ุจู†ู†ุงุฏูŠ ุนู„ู‰ GC.SuppressFinalize()ุŒ ุงู„ู…ูŠุซูˆุฏ ุฏูŠ ู…ุด ุจุชุงุฎุฏ ู‚ูŠู…ุฉ BooleanุŒ ุฏูŠ ุจุชุงุฎุฏ ุงู„ู€ object referenceุŒ ูŠุนู†ูŠ ุจุชุชูƒุชุจ ุจุงู„ุดูƒู„ ุฏู‡: GC.SuppressFinalize(this).
  • ุฏูˆุฑุฉ ุญูŠุงุฉ ุงู„ู€ Destructor: ุงู„ู„ูŠ ุจูŠุญุตู„ ุฅู† ุงู„ู€ GC ู„ู…ุง ุจูŠู„ุงู‚ูŠ object ู„ูŠู‡ Finalizer (ุฃูˆ Destructor) ูˆู…ุจู‚ุงุด ู…ุณุชุฎุฏู…ุŒ ุจูŠู†ู‚ู„ู‡ ู„ุทุงุจูˆุฑ ุงุณู…ู‡ F-Reachable Queue. ูˆุฌูˆุฏู‡ ููŠ ุงู„ุทุงุจูˆุฑ ุฏู‡ ุจูŠุฎู„ูŠู‡ ูŠูุนุชุจุฑ (Alive) ุจุงู„ู†ุณุจุฉ ู„ู„ู€ GC ุงู„ุญุงู„ูŠุŒ ูุจุงู„ุชุงู„ูŠ ุจูŠู†ุฌูˆ ู…ู† ุนู…ู„ูŠุฉ ุงู„ุชู†ุธูŠู ุงู„ุญุงู„ูŠุฉ ูˆุจูŠุชุฑู‚ู‰ ุชู„ู‚ุงุฆูŠู‹ุง ู„ู„ุฌูŠู„ ุงู„ู„ูŠ ุจุนุฏู‡. ุจุนุฏูŠู† ุจูŠุฌูŠ Thread ู…ุฎุตุต ู„ู„ู€ Finalizer ูŠู†ูุฐ ูƒูˆุฏ ุงู„ุชู†ุถูŠูุŒ ูˆููŠ ุฏูˆุฑุฉ ุงู„ู€ GC ุงู„ู„ูŠ ุจุนุฏู‡ุง ุจูŠุชู… ู…ุณุญู‡ ุฃุฎูŠุฑู‹ุง.
  • ุงู„ู€ Managed Heap ูˆุงู„ู€ Stack: ู…ู‡ู… ู†ูˆุถุญ ุฅู† ุงู„ู€ Garbage Collector ุจูŠุดุชุบู„ ุฃุณุงุณู‹ุง ุนู„ู‰ ุงู„ู€ Managed Heap (ุงู„ู…ูƒุงู† ุงู„ู„ูŠ ุจูŠุชุฎุฒู† ููŠู‡ ุงู„ู€ Reference Types ุฒูŠ ุงู„ู€ Classes). ุฃู…ุง ุงู„ู€ Value Types (ุฒูŠ ุงู„ู€ int ูˆ ุงู„ู€ structs) ูุบุงู„ุจุงู‹ ุจุชุชุฎุฒู† ุนู„ู‰ ุงู„ู€ StackุŒ ูˆุงู„ู€ Stack ุจูŠู†ุถู ู†ูุณู‡ ุจู†ูุณู‡ ุจู…ุฌุฑุฏ ู…ุง ุงู„ู€ Method ุชุฎู„ุตุŒ ูู…ุด ุจูŠุญุชุงุฌ ุชุฏุฎู„ ู…ู† ุงู„ู€ GC.
  • ู„ูŠู‡ ุงู„ู€ Generation 0 ุณุฑูŠุนุŸ: ุงู„ู€ Gen 0 ุจูŠูƒูˆู† ู…ุณุงุญุชู‡ ุตุบูŠุฑุฉ ูˆุบุงู„ุจู‹ุง ุจูŠูƒูˆู† ู…ูˆุฌูˆุฏ ุฌูˆู‡ ุงู„ู€ CPU CacheุŒ ูุนู…ู„ูŠุฉ ุชู†ุธูŠูู‡ ุจุชูƒูˆู† ุณุฑูŠุนุฉ ุฌุฏู‹ุง ูˆู…ุด ุจุชุฃุซุฑ ุนู„ู‰ ุฃุฏุงุก ุงู„ุชุทุจูŠู‚.

ุงู„ู€ .NET 10 ุฌุงูŠุจ ู…ุนุงู‡ ุชุญุณูŠู†ุงุช ู‚ูˆูŠุฉ ุฌุฏู‹ุง ุชุฎุต ุงู„ู€ Garbage Collector ุนุดุงู† ูŠู‚ู„ู„ ุงู„ุถุบุท ุนู„ูŠู‡ ูˆูŠุฒูˆุฏ ุงู„ุฃุฏุงุก:

  1. ุงู„ู€ Stack Allocation for Small Arrays: ููŠ .NET 10ุŒ ุงู„ู€ JIT ุจู‚ู‰ ุฃุฐูƒู‰ุŒ ูˆุจูŠู‚ุฏุฑ ูŠุญู„ู„ ุงู„ูƒูˆุฏ (Escape Analysis). ู„ูˆ ู„ู‚ู‰ ุฅู†ูƒ ุนุงู…ู„ Array ุตุบูŠุฑ (ุณูˆุงุก Value Type ุฃูˆ Reference Type) ูˆู…ุด ู‡ูŠุฎุฑุฌ ุจุฑู‡ ุญุฏูˆุฏ ุงู„ู€ Method ุงู„ู„ูŠ ุงุชุนู…ู„ ููŠู‡ุงุŒ ุจูŠุญุฌุฒู‡ ุนู„ู‰ ุงู„ู€ Stack ุจุฏู„ ุงู„ู€ Heap. ุฏู‡ ุจูŠู‚ู„ู„ ุนุฏุฏ ุงู„ู€ objects ุงู„ู„ูŠ ุงู„ู€ GC ู…ุญุชุงุฌ ูŠุฑุงู‚ุจู‡ุง ูˆูŠู…ุณุญู‡ุง.
  2. ุงู„ู€ DATAS (Dynamic Adaptation To Application Sizes): ุงู„ู†ุธุงู… ุฏู‡ ุจู‚ู‰ ู…ุชูุนู„ ุจุดูƒู„ ุชู„ู‚ุงุฆูŠ ููŠ ู…ุนุธู… ุงู„ุฅุนุฏุงุฏุงุชุŒ ูˆุฏู‡ ุจูŠุฎู„ูŠ ุงู„ู€ GC ูŠุถุจุท ู…ุณุงุญุงุช ุงู„ุฐุงูƒุฑุฉ ุจุดูƒู„ ุฏูŠู†ุงู…ูŠูƒูŠ ุญุณุจ ุงุญุชูŠุงุฌ ุงู„ุชุทุจูŠู‚ ุงู„ูุนู„ูŠุŒ ู…ู…ุง ูŠู‚ู„ู„ ู…ู† ุงุณุชู‡ู„ุงูƒ ุงู„ุฐุงูƒุฑุฉ ุจุดูƒู„ ูƒุจูŠุฑ.
  3. ุชุญุณูŠู†ุงุช ุงู„ู€ Write-Barrier (ุฎุงุตุฉ ู„ู…ุนุงู„ุฌุงุช Arm64): ุงู„ู€ Write-Barrier ู‡ูˆ ู…ูŠูƒุงู†ูŠุฒู… ุจูŠุณุชุฎุฏู…ู‡ ุงู„ู€ GC ุนุดุงู† ูŠุชุชุจุน ู„ูˆ object ู‚ุฏูŠู… (ููŠ ุฌูŠู„ ุฃูƒุจุฑ) ุดุงูˆุฑ ุนู„ู‰ object ุฌุฏูŠุฏ. ููŠ .NET 10 ุชู… ุชุญุณูŠู† ุงู„ู…ูŠูƒุงู†ูŠุฒู… ุฏู‡ ูˆุชู‚ู„ูŠู„ ุงู„ุงุนุชู…ุงุฏ ุนู„ูŠู‡ ููŠ ุจุนุถ ุงู„ุญุงู„ุงุชุŒ ูˆุฏู‡ ุฃุฏู‰ ู„ุชู‚ู„ูŠู„ ูˆู‚ุช ุงู„ุชูˆู‚ู (Pause Times) ุฃุซู†ุงุก ุนู…ู„ ุงู„ู€ GC ุจู†ุณุจ ุจุชูˆุตู„ ู„ู€ 20%.