Microsoft said – ‘Please recycle every 29 hours’ – and without giving it another thought, we all blindly did so. I never gave this ‘default IIS behavior’ any thought – but this guy did. Why exactly DO we recycle IIS’s app pool every 29 hours (or less, in some cases)? Are we so petrified of our application’s memory consumption that we are certain it will exhibit ‘leaks’?
How bad WOULD it be if we ignored Microsoft and stopped recycling our app pools altogether?
All the answers are in this post (by the author of Agatha – Service Request Response Layer). I have nothing much to add to this post – except for ONE best practice.
Start (your design) with interfaces that implement IDisposable
You already know that you are supposed to start your design with an interface. Not just for your services layer, but also for your domain layer, UI layer, persistence layer and every other layer in your application. The only thing I would add to that is – always start your design with interfaces that implement IDisposable. So, all your starting designs should look like this:
To go a step further, you can provide a default implementation of the IDisposable (see sample below) – that every class in your project should try and inherit. Yes (in c#) – you are limited to inheriting from just one base class – but if it has to be just one, the Disposable is the one you should inherit from. For additional functionality that you may want to leverage from other classes, use interface implementations – since you are not limited in the number of interfaces that you can implement.
Any class that inherits from the Disposable class defined above, will get two things out of the box:
- A Dispose() method that can be called by whoever is using this class.
- A set of two virtual methods that can be overridden – DisposeManagedResources and DisposeUnmanagedResources.
This may not seem like a big deal, but it actually is. The default ‘recycling’ nature of the IIS app pool , is effectively masking memory leaks. At some point, the ‘restarts’ will not be enough – and the code will have to be thoroughly inspected for such leaks.
To avoid getting into this situation in the first place, use the IDisposable pattern (the snippet above is a full implementation of this pattern). Most applications, though utilizing the power of interfaces fully (starting with Service contract interfaces for example), fail to implement IDisposable. They trust the garbage collector to do its job efficiently. In reality, the garbage collector needs all the help it can get – and if you can manually Dispose() of all your objects (at least the ones interacting with the filesystem or containing static resources), you will have helped the GC a great deal.
Turn off the automatic pool recycling – and try to identify the underlying memory leaks in your app. Several 3rd party tools – such as RedGate’s ANTs memory profiler, JetBrain’s dottrace and SciTech’s memory profiler – can help.