IList<T> Custom Collections

Memory profiling for .NET developers

Moderators: StephenC, Alex.Davies, AndrewH, melvyn.harbour

IList<T> Custom Collections

Postby Ken Alexander » Fri Jul 17, 2009 9:34 pm

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
Ken Alexander
 
Posts: 1
Joined: Fri Jul 17, 2009 9:26 pm

Postby StephenC » Mon Jul 20, 2009 9:00 am

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
StephenC
 
Posts: 306
Joined: Mon Oct 15, 2007 9:18 am
Location: Cambridge

Postby StephenC » Mon Jul 20, 2009 11:21 am

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

If you take another snapshot does the instance still remain?

Stephen
StephenC
 
Posts: 306
Joined: Mon Oct 15, 2007 9:18 am
Location: Cambridge

Postby sandyp » Fri Sep 18, 2009 11:20 am

I have the same situation. The very simple WinForms test:

Code: Select all
    public class MyInfoClass
    {
        string _name = String.Empty;

        public MyInfoClass(string name)
        {
            _name = name;
        }

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
    }

    public partial class Form1 : Form
    {
        private List<MyInfoClass> _list = null;

        public Form1()
        {
            InitializeComponent();
            List<MyInfoClass> list = new List<MyInfoClass>();
            list.Add(new MyInfoClass("1"));
            list.Add(new MyInfoClass("2"));
            list.Add(new MyInfoClass("3"));

            _list = list;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            _list = null;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            _list.Clear();
            _list = null;
            GC.Collect();
        }
    }


After pressing button2, I have [GC Handle]->System.Object[]->MyInfoClass[] chain and it's remained in memory after new snapshots. Any ideas why?
sandyp
 
Posts: 2
Joined: Fri Sep 18, 2009 11:15 am

Postby AndrewH » Fri Sep 18, 2009 12:06 pm

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.
AndrewH
 
Posts: 134
Joined: Thu Aug 17, 2006 3:44 pm

Postby sandyp » Mon Sep 21, 2009 3:16 pm

Yes, it looks strange but your findings explain everything. Thanks!
sandyp
 
Posts: 2
Joined: Fri Sep 18, 2009 11:15 am


Return to ANTS Memory Profiler Previous Versions

Who is online

Users browsing this forum: No registered users and 0 guests

cron