2

I'm having an issue freeing memory from a List<> when items are removed. It's the strangest thing, memory is only released from the application when a second set of items are added and removed from the List<>. I was able to illustrate the issue using this simple console application:

C# .Net4.0

namespace MemoryTestApp
{
    class Program
    {
        static int numObjects = 1000;
        static int objectSize = 10000;

        class Obj
        {
            byte[] buffer = new byte[objectSize];
            public Obj()
            {
                buffer[0] = 1;
                buffer[buffer.Length - 1] = 1;
            }
        }

        private static List<Obj> list = new List<Obj>();

        static void Main(string[] args)
        {
            while(true)
            {
                Console.WriteLine("Press Enter to add {0} objects to list...", numObjects);
                Console.ReadLine();

                //add to list of objects
                for (int i = 0; i < numObjects; i++)
                {
                    list.Add(new Obj());
                }

                //double num objects for next round so we can see which block of memory is released
                numObjects = numObjects * 2;

                Console.WriteLine("Press Enter to remove objects from list...");
                Console.ReadLine();

                foreach (Obj _obj in list.ToList())
                {
                    list.Remove(_obj);
                }

                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
                GC.WaitForPendingFinalizers();

                Console.WriteLine("Press Enter to trim excess from list...");
                Console.ReadLine();

                list.TrimExcess();

                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
                GC.WaitForPendingFinalizers();
            }
        }
    }
}

Basically, the block of memory used by items added in round N is only released after new items are added then removed in round N+1 (approximately, this is more easily visible in rounds > 3). I tested the issue using the resolution here and here however the behavior didn't appear to change at all.

This is probably still related to GC behavior but even given the references above I can't make it work as I expect it should. So where is the fault in my code, or my expectations? I greatly appreciate any assistance.

Community
  • 1
  • 1
khargoosh
  • 1,450
  • 15
  • 40
  • "memory is only released from the application"... ? Could you please clarify how you measure memory usage and what you see/expect from that application? – Alexei Levenkov Sep 02 '15 at 02:12
  • I'm simply watching the private memory usage in the resource monitor, however I have profiled the test app and each `N` round of object memory continues to be identified as `reachable instances` until after the round `N+1` objects are added and removed. I was expecting the round `N` instances to be unreachable, and the round `N` memory to be released, as soon as the objects in round `N` are removed and the list is trimmed. – khargoosh Sep 02 '15 at 02:19

0 Answers0