I coded a windows service application and tested it throughout its development cycle. This windows service it’s doing work all the time. So one day I left it running the whole night and when came back to the office the next day I found that the service had stopped working due to an OutOfMemoryException exception.
I thought it was probably something else but then I ran it again this time monitoring it with Process Explorer (a very useful free application available from Microsoft) and saw it was increasing its memory consumption consistently.
The graphic in Process Explorer looks like the one below. Note how the memory consumption never stops growing.
By trial and error we could isolate the cause of this memory leak. It turned out to be the following line of code:
This XmlSerializer object is created thousands of times during the application lifecycle and it never releases the underlying memory resources it creates. According to the MSDN Magazine article Identify and Prevent Memory Leaks in Managed Code1 the XmlSerializer constructor we were using creates “temporary” assemblies which are never disposed:
“This overload of the XmlSerializer constructor does not cache the dynamically generated assembly, but generates a new temporary assembly every time you instantiate a new XmlSerializer! The app is leaking unmanaged memory in the form of temporary assemblies.”
The solution to this problem was in fact quite simple (after many hour of troubleshooting, debugging and research though): instead of instantiating a new XmlSerializer object in our DeserializeObject() method (which is invoked thousands of times during the application lifecycle) we set a member variable of this type and we instantiated it once in the class constructor.
After doing that the memory consumption stabilized as you can see in the following picture:
No comments:
Post a Comment