IList<T> Custom Collections

When using IList<T> for a custom collection. It appears that the underlying array is left in memory after the collection has been GC'd. It says 1 live instance of a size of 16 bytes.

I don't understand why it is left in memory. Any ideas would be appreciated.

Thanks,

Ken

Comments

  • The object retention graph is designed to show what is referencing an object and therefore preventing it from being GC'd.

    This should help you identify what's keeping the remaining instance in memory.

    Stephen
  • There's another possibility that it's simply on the Finalizer queue.

    If you take another snapshot does the instance still remain?

    Stephen
  • I have the same situation. The very simple WinForms test:
    public class MyInfoClass
        &#123;
            string _name = String.Empty;
    
            public MyInfoClass&#40;string name&#41;
            &#123;
                _name = name;
            &#125;
    
            public string Name
            &#123;
                get
                &#123;
                    return _name;
                &#125;
                set
                &#123;
                    _name = value;
                &#125;
            &#125;
        &#125;
    
        public partial class Form1 : Form
        &#123;
            private List&lt;MyInfoClass&gt; _list = null;
    
            public Form1&#40;&#41;
            &#123;
                InitializeComponent&#40;&#41;;
                List&lt;MyInfoClass&gt; list = new List&lt;MyInfoClass&gt;&#40;&#41;;
                list.Add&#40;new MyInfoClass&#40;"1"&#41;&#41;;
                list.Add&#40;new MyInfoClass&#40;"2"&#41;&#41;;
                list.Add&#40;new MyInfoClass&#40;"3"&#41;&#41;;
    
                _list = list;
            &#125;
    
            private void button1_Click&#40;object sender, EventArgs e&#41;
            &#123;
                _list = null;
            &#125;
    
            private void button2_Click&#40;object sender, EventArgs e&#41;
            &#123;
                _list.Clear&#40;&#41;;
                _list = null;
                GC.Collect&#40;&#41;;
            &#125;
        &#125;
    

    After pressing button2, I have [GC Handle]->System.Object[]->MyInfoClass[] chain and it's remained in memory after new snapshots. Any ideas why?
  • It took me a little while to work this one out :) It's odd, but you're not seeing something that indicates a memory leak here, I think.

    System.Generic.List contains a static reference to an empty array, so that it can represent 0 item lists more effectively: that's the array that you're seeing after you click the button. Note that it's actually there beforehand as well: you'll see two arrays when you take a snapshot before clicking the button.

    It's not a memory leak, but rather an implementation detail of the .NET framework. You'll note that the array is always very small and there's only every one of these.

    The pattern [GC Handle]->System.Object[]->MyInfoClass[] usually indicates a static variable: this is how they're implemented internally by the .NET framework. The profiler does try to identify which variable contains a particular object provided you're using .NET 2 or later, but there are some CLR limitations that prevent it from working reliably in all cases. Generic classes, such as List<T> is one such example, unfortunately, which is why this gets presented in this way.
    Andrew Hunter
    Software Developer
    Red Gate Software Ltd.
  • Yes, it looks strange but your findings explain everything. Thanks!
Sign In or Register to comment.