How good is the garbage collector?

Just how good is it

Is it a C# feature or .NET Framework feature

Thanks



Answer this question

How good is the garbage collector?

  • DarkByte

    Quite a bit of the .NET Framework simply wraps around existing Win32 or COM(+) functionality. WinForms is an excellent example, where you still have a HWND backing every window and control. GDI+ is another good example. Take a look at GdiPlus.dll, the Win32 DLL that implements the actual GDI+ functionality. (You can find P/Invoke signature for GdiPlus.dll at http://www.pinvoke.net/default.aspx/gdiplus.GdipAddPathArc and related subsections.) You'll quickly see that System.Drawing is a thin wrapper around it. (GDI+ - and GdiPlus.dll - originally shipped with WinXP, but are installed by the .NET Framework to provide a standard platform for all .NET applications.)
     
    This is why WinForms has its limitations - limitations imposed by the original Win32 windowing model. For example, although you can logically create a spreadsheet out of textbox controls, the overhead would be enormous because every cell would have its own HWND. Also everything in the Win32 windowing model (and hence WinForms) is pixel-based. So interfaces don't scale well as you change the resolution. These are just two of the reasons for Windows Presentation Foundation (WPF or Avalon). To move beyond the Win32 windowing model to a scalable, composible windowing framework.
     
    Enough of this tangent... Back to our regularly scheduled post... To answer your question, yes, you should be fine with your own classes simply composed from base types and structs. But, like anything in performance work, your mileage may vary. So code up a representative example and take a look at its memory allocation characteristics in the CLR Profiler, or similar memory profiler. Also remember that micro benchmarks may not accurately model your final system. So you'll want to write some minimal production code that demonstrates your usage pattern.
     
    Hope that helps.


  • chaney

    Thanks for the links.  They are the info I was looking for.
  • mmalagelada

    By creating 50,000 ComboBoxes, you've created 50,000 Win32 window handles that need to be cleaned up by a finalizer since you're not calling Dispose on the ComboBoxes. (The WinForm ComboBox is simply a thin wrapper around the ComboBox in the Windows Common Controls. So it has an associated hwnd that must be cleaned up.) This automatically causes the ComboBoxes to be pushed into Gen 1. Try changing your test to an object that does not wrap an unmanaged resource, such as an object. You should see nicer behaviour with:
     
    A[ i ] = new object();
     
    N.B. When you're looking at Task Manager, you are looking at the process' working set or how much memory the operating system has allocated to it. The GC frees managed heap memory so that it doesn't have to request more memory from the OS. (Just because the GC freed memory doesn't mean that it will suddenly become available to the OS again.) The GC has heuristics for returning excess reclaimed memory to the OS.


  • _Bosch_

    Personally I have found the .NET garbage collector to be very efficient and well-implemented. Usually it just works, but you should understand how garbage collectors work so that you don't run into a "mid-life crisis". (This is true of any programming environment, though.) Check out the CLR Profiler (available free from Microsoft) and Rico Mariani's blog posts on the GC.
     
     
    The GC is a feature of the CLR (or Common Language Runtime), which is the runtime for all applications that target the .NET Framework. The CLR jits (just-in-time compiles) MSIL (Microsoft Intermediate Language) to native code (x86/x64/Itanium), which the CPU can actually execute. The job of compilers that target the .NET Framework, such as the C# or VB.NET compilers, is to produce MSIL. So the workings of the GC is wholely the domain of the CLR.


  • AceJay

    Well, I tried putting the theory to practice.  I have the following code and wired a button to run method R on each click (if you see a lightbulb, it's open bracket i close bracket):

     

    public static object[] A;
    public static void R()
    {

      A = new object[50000];
      for (int i=0; i<A.Length; i++) AIdea=new ComboBox();

      MessageBox.Show("Hi");
      A =
      new object[1];

    }

     

    I haven't got round to learning to use the Profiler.  But by looking at Task Manager, the Mem Usage keeps climbing each time I click the button.  I waited for 30 minutes, and still Mem Usage didn't come down.  Have I done something wrong

    Thanks in advance.


  • Gseese2

    Thanks.  I didn't know it was this subtle.  I always thought System.Windows.Form was a truly .NET Managed namespace.  Is it still the same in .NET Framework 2.0

    I have data that has to be allocated/reallocated repeatedly.  So something like an array of int or my own class built from struts and value types will be 100% recovered if I simply re-new it


  • How good is the garbage collector?