Tuesday, 2 April 2013

Living happily with the GC

Wed 6th March Richard Blewett

This lecture was one of the more practical ones and mainly focused on using PerfMon to show how the GC works when various bits of code are run.  I'm not going to give a description of how the GC works, instead I'll concentrate on coding changes we can/should be making.

The main goal is to collect as much memory in Generation 0 as possible since Generations 1/2 are around 10 and 100 times slower respectively.

It's worth noting that as of .net 4 you can choose Asynchronous garbage collections for Generation 2.

There is a stage in garbage collection called Finalization which happens in case Dispose wasn't called on an object.  This is run using the Finalizer thread which is slow and its timing is unpredictable.  Simply by adding a destructor to a C# object the number of objects allocated per second drops by about a factor of 15.  If you need to remove references to unmanaged objects (e.g. icon/filestream/sqlconnections) consider using SafeHandle instead.

This example looks strange but helps if a GC happens half way through the Load function:
    
    void LoadData(string s)
    {
        this.data = null;
        this.data = XDocument.Load(s);
    }

Actions:

  • Run load tests with PerfMon garbage collections switched on.
  • Look at our use of destructors
  • Consider using SafeHandle instead of IDisposable
  • Profile to see what the current state of play is w.r.t memory usage / GC time.

No comments:

Post a Comment