CodeSOD: Making a Weak Reference
There are times when performance absolutely matters. And the tech lead that Janell was working with (previously) was absolutely certain that their VB.Net project needed to be "designed for performance". Performance was so important that in the final design, they used a home-brewed JSON database (which, at its lowest level, was just a JSON file on disk), and it took 7 round-trips to their home-brewed database to read a single record.
Despite all this attention on performance, the system had a memory leak! As we've covered in the past, garbage-collected languages can have leaks, but they may take a little more effort than the old-school versions. Janell fired up a debugger, looked at the memory utilization, and started trying to figure out what the problem was.
The first thing Janell noticed was that there were millions of WeakReference objects. A WeakReference can hold a reference to an object without preventing garbage collection. This is the sort of thing that you might use to prevent memory leaks, ensuring that objects get released.
A little more poking revealed two layers to the problem. First, every business object in the application inherited from BaseObject. Not the .NET object type that's the base class for all objects, but a custom BaseObject. Every class had to inherit from BaseObject.
Public Class BaseObject Public Sub BaseObject() ' Snip Memory.Register(Me) ' Snip End SubEnd Class
Buried in this custom constructor which hooked all sorts of inner-platform extensions into the base class of all classes, was that Memory.Register call.
Public Class Memory Private Shared memory As LinkedList(Of WeakReference(Of BaseObject)) Public Shared Sub Register(obj As BaseObject) memory.AddLast(New WeakReference(Of BaseObject)(obj)) End Sub ' SnipEnd Class
Once again, the tech lead wanted to "validate performance", and one of the ways they did this was to track all the business objects that were ever created. By using a WeakReference, they guaranteed that all the actual business objects could still be cleaned up... but nothing ever cleaned up the WeakReference objects themselves.
Janell fixed the leak in the simplest way possible: by deleting the Memory class and any reference to it.
[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!