Memory Management

Tracking Dangling Object References In Silverlight

12 commentsWritten on August 4th, 2009 by
Categories: Memory Management, Silverlight

One of the downsides of working with a young platform like Silverlight is that the tool support isn't quite 'there' yet, particularly when it comes to profiling for performance and memory usage. And as you may or may not know, Silverlight makes it very easy to introduce memory leaks into your code. Since you can't just attach a memory profiler to your Silverlight application, optimizing memory usage or tracking down a leak can be a real pain in the ass.

In the past i have resorted to grabbing a memory dump of the browser and analyzing the content of the managed heap with windbg to track down which instances where being kept in memory. While this works, it's pretty time consuming and can quite easily lead you down the wrong path. One of the most important things that you want to know in this specific case is: which types are being kept in memory, and how many of them?

In this case, being able to query something during debugging regarding which instances are still kept alive in memory at certain times is sufficient for me. So i came up with the following class:

    public static class ObjectTracker

    {

        private static readonly object monitor = new object();

        private static readonly List<WeakReference> objects = new List<WeakReference>();

        private static bool? shouldTrack;

 

        public static void Track(object objectToTrack)

        {

            if (ShouldTrack())

            {

                lock (monitor)

                {

                    objects.Add(new WeakReference(objectToTrack));

                }

            }  

        }

 

        private static bool ShouldTrack()

        {

            if (shouldTrack == null)

            {

                shouldTrack = Debugger.IsAttached;

            }

 

            return shouldTrack.Value;

        }

 

        public static IEnumerable<object> GetAllLiveTrackedObjects()

        {

            lock (monitor)

            {

                GC.Collect();

                return objects.Where(o => o.IsAlive).Select(o => o.Target);

            }

        }

    }

The idea is basically to just keep a list of WeakReferences of objects you want to track (only if a debugger is attached), and later on you can 'query' the live instances through the GetAllLiveTrackedObjects method. This method obviously performs a full garbage collect to make sure only objects that are really still alive are returned. Again, you should almost never do a GC.Collect() manually, but in this case the method will only be called while you're debugging.

Then, you strategically put the following line in the constructor of every kind of type you'd like to track:

            ObjectTracker.Track(this);

I have that line in the constructor of my base View class, my base Controller class and in my base Disposable class. So now, when i want to check if there are any dangling references to instances of types that i really don't want hanging around, i can just do something like this:

            var liveObjects = ObjectTracker.GetAllLiveTrackedObjects();

 

            if (Debugger.IsAttached)

            {

                Debugger.Break();

            }

And then manually inspect the content of the liveObjects collection. It's far from perfect, but at least it's an easy way to at least know which instances (that i care about) are being kept in memory. It'll do until we get better tool support :p

The Joys Of Debugging ASP.NET Memory Leaks

5 commentsWritten on April 6th, 2009 by
Categories: .NET bugs, ASP.NET, Memory Management

One of my coworkers describes a very interesting memory leak he just fixed. Be sure to read his post to get the entire story.

We basically had a custom UserControl which contained (among other things) a Repeater which would render another custom UserControl. Nothing really weird there, right? The problem was that the custom UserControl that was created by the Repeater explicitly needed to be disposed. No problem, System.Web.UI.Control implements IDisposable so we could just override the Dispose method, perform our cleanup there and then proceed with the base Dispose implementation.

Now, i'm far from an ASP.NET expert but i was under the impression that all Page and UserControl instances would always have their Dispose method called if they were created by other ASP.NET controls (containing pages or controls). After all, what's the point in implementing IDisposable in the base Control class if you're not even going to guarantee proper usage of the pattern, right?

Well, as Kristof describes in his post, there is at least one situation where a UserControl is not disposed of, even though it was created by a Repeater. In our case, the leak was subtle. It took a stress test of 10 hours with a load that would be comparable to real world usage of one month to expose the leak. A lot of people would say "oh, let's just recycle the application pool periodically and everything is A-OK". But the very idea of having to recycle an application pool periodically to keep a system up and running is just a cop out to me. Good code should not require periodic restarts. Period.

I wonder how many ASP.NET WebForms applications might actually have the same (or at least similar) problem(s) like the one Kristof encountered. If everyone keeps recycling their application pools periodically, we unfortunately may never found out.

Silverlight’s ProgressBar And Possible Memory Leaks

6 commentsWritten on February 25th, 2009 by
Categories: Memory Management, Silverlight

This has got to be the weirdest memory leak i've ever investigated. We have this kick-ass Silverlight application, but unfortunately it suffered from very high memory usage that went up rather rapidly. So i attached windbg to the browser's process, took a memory dump and checked out which objects were still available in the heap. Much to my surprise, pretty much everything we instantiated was retained in memory and never got removed from the heap.

So i started looking into the usual things: making sure disposable instances where disposed of properly, that evenhandlers were unregistered properly, etc. I went over the code and it seemed to be alright. Stepping through the code with a debugger verified that disposables were indeed disposed of, and that all event handlers were unregistered.

So why was pretty much everything kept in memory? Further research with windbg showed that every ProgressBar instance that was ever created (and we use a lot of them, basically every time we make a call to the application server) kept a reference to the UserControl it was placed on and thus, kept the UserControl and all the references it contained alive. In our case, that includes our presentation models and obviously all of the contained child UserControls.

The ProgressBar is defined like this:

<ProgressBar Height="40" Style="{StaticResource ourKickAssStyle}" VerticalAlignment="Center" Width="40" IsIndeterminate="True"/>

The key here is the usage of the IsIndeterminate property... setting this to true causes the ProgressBar to move continuously without respecting any current Value property. You know, basic stuff. The thing is... if i change the definition of the ProgressBar to this:

<ProgressBar Height="40" Style="{StaticResource ourKickAssStyle}" VerticalAlignment="Center" Width="40" />

The memory leak suddenly went away :)

Obviously, this isn't a solution because the ProgressBar now doesn't really indicate any progress and we need our kick ass custom animation to retain the coolness of the application.

So for some reason, when you set the ProgressBar's IsIndeterminate property to true, it actually keeps all of its references alive even when the ProgressBar control is removed from its parent control. Happy times.

We now have the following ugly method in one of our base UI classes:

        private static void StopProgressBars(DependencyObject dependencyObject)
        {
            var count = VisualTreeHelper.GetChildrenCount(dependencyObject);
 
            for (int i = 0; i < count; i++)
            {
                var child = VisualTreeHelper.GetChild(dependencyObject, i);
                if (child != null)
                {
                    var progressBar = child as ProgressBar;
 
                    if (progressBar != null)
                    {
                        progressBar.IsIndeterminate = false;
                    }
 
                    StopProgressBars(child);
                }
            }
        }

Great Links On Using Garbage Collection Efficiently

1 Comment »Written on January 11th, 2009 by
Categories: Memory Management

I usually try to avoid posts that merely link to other stuff, but these links are just too good:

The Resolvable

1 Comment »Written on December 21st, 2008 by
Categories: Castle Windsor, Memory Management

I wrote a post last week about a memory leak i had introduced in my code due to not properly releasing resolved components through the Windsor IoC container. I wanted to try to make sure that i'd never make that mistake again and this is the approach i came up with.

If you're using an IOC container it's important to not use it all over the place. You basically use it in as few places as possible to resolve a component and you let the container sort out all of the dependencies. So in the few places where you use the container directly, you need to resolve the component, and in case of transient components you also need to release them through the container. Releasing it is very easy to forget, so i wanted something that would guarantee that the component would be properly released. Enter the Resolvable class:

    public class Resolvable<T> : Disposable
    {
        private readonly T instance;
 
        public Resolvable() : this(null) {}
 
        public Resolvable(object argumentsAsAnonymousType)
        {
            if (argumentsAsAnonymousType == null)
            {
                instance = IoC.Container.Resolve<T>();
            }
            else
            {
                instance = IoC.Container.Resolve<T>(argumentsAsAnonymousType);
            }
        }
 
        public T Instance
        {
            get { return instance; }
        }
 
        protected override void DisposeManagedResources()
        {
            IoC.Container.Release(instance);
        }
    }

The Resolvable class inherits from my Disposable class, so the Disposable pattern is correctly implemented.

From now on, instead of calling the container directly, i just instantiate a new Resolvable in a using block. Let's try it out.

I'm reusing my test component with a dependency from one of the previous posts:

    public interface IDependency : IDisposable
    {
        bool Disposed { get; set; }
    }
 
    public class MyDependency : IDependency
    {
        public bool Disposed { get; set; }
 
        public void Dispose()
        {
            Disposed = true;
        }
    }
 
    public interface IController : IDisposable
    {
        bool Disposed { get; set; }
        IDependency Dependency { get; }
    }
 
    public class Controller : IController
    {
        public IDependency Dependency { get; private set; }
 
        public Controller(IDependency myDependency)
        {
            Dependency = myDependency;
        }
 
        public void Dispose()
        {
            Dependency.Dispose();
            Disposed = true;
        }
 
        public bool Disposed { get; set; }
    }

Now, instead of resolving an IController directly through the container and having to dispose of it, i just do this:

        [Test]
        public void ResolvableInstanceIsProperlyReleasedAfterDisposal()
        {
            IoC.Container.Register(Component.For<IController>().ImplementedBy<Controller>().LifeStyle.Transient);
            IoC.Container.Register(Component.For<IDependency>().ImplementedBy<MyDependency>().LifeStyle.Transient);
 
            IController controller;
            IDependency dependency;
 
            using (var resolvable = new Resolvable<IController>())
            {
                controller = resolvable.Instance;
                dependency = controller.Dependency;
            }
 
            Assert.IsTrue(controller.Disposed);
            Assert.IsTrue(dependency.Disposed);
            Assert.IsFalse(IoC.Container.Kernel.ReleasePolicy.HasTrack(controller));
            Assert.IsFalse(IoC.Container.Kernel.ReleasePolicy.HasTrack(dependency));
        }

The container doesn't hold the reference to the instance, and both the instance and its dependency is properly disposed.