none
Memory leaks in a List RRS feed

  • Question

  • Hallo,

    I'm working on an asp.net application and I have memory leaks problem.
    I'm using Ants profiler for the analyse.

    I have found out, that one of the List object (List Of (MyObj) ) that I'm using is leaking.
    I made a small test application in which I create the list, fill it with MyObj objects and then assign the list with 'Nothing' hoping that the GC would pick it.
    What I've noticed is that after running the application .net keeps an array (!!) of MyObj[] refered by array of System.Object[].

    I assume that this MyObj[] array is the .net internal implementation of the 'List Of (MyObj)' yet I don't understand why .net keep a reference to it, and how to free this memory.

    any advice would be appreciated

    lovely greetings

            Cavin
    Tuesday, September 15, 2009 11:14 AM

Answers

  • There shouldn't be any memory leak. List<T> has been used for years by thousands of developers and personally by me :).
    My opinion is that some other object keeps reference to your list (maybe some peace of code called ToArray method and keeps this array alive). This is the only possible IMHO explanation here.

    Vitaliy Liptchinsky http://dotnetframeworkplanet.blogspot.com/
    • Proposed as answer by eryang Monday, September 21, 2009 7:25 AM
    • Marked as answer by eryang Thursday, September 24, 2009 1:49 AM
    Tuesday, September 15, 2009 12:45 PM
  • Hi Cavin,
    The case may caused by two reasons:
    1. When invoke ToArray() method of a List<T>, a new T[] will be created and its values are copied from the List<T>, so, even if the List<T> is GCed, the new T[] still alive. Just as Vitaliy said, review your code to find out ToArray operations.
    2. If size of the inner T[] is big enough, it will be allocated at the Large Object Heap (LOH). since GC on generation 0 is more frequent than on LOH, the situation (the inner T[] still alive but the List<T> has been GCed) can happen. In this condition, I don't think it is a memory leak, it is just because the size of objects on LOH haven't reach threshold, so the GC on LOH is not triggered.

    Thanks,
    Eric


    Please remember to mark helpful replies as answers and unmark them if they provide no help.
    • Marked as answer by eryang Thursday, September 24, 2009 1:49 AM
    Monday, September 21, 2009 9:55 AM

All replies

  • Hallo,

    Yes, internally List<T> uses an array of T[].
    This memory will be reclaimed by the upoming GC. Try to use GC.Collect() after setting list reference to null and verify if there is really a memory leak. Probably some other object keeps reference on instance of your list.
    Vitaliy Liptchinsky http://dotnetframeworkplanet.blogspot.com/
    Tuesday, September 15, 2009 11:30 AM
  • Hallo Vitaly,

    Thanks for your reply.

    When calling GC.Collect the Gen 0 Heap size increases.
    The private bytes stays constant.

    If i'm not mistaken, this does indicate a memory leak problem. isn't it?

    I find it weired that I have a reference to the array of MyObj[] hence I never refered to the Array
    but to the List. (and the List indeed does not exists anymore)

    any idea?

    lovely greetings

          Cavin


    Tuesday, September 15, 2009 11:47 AM
  • myList.Clear() should release references to elements.
    • Edited by Wole Ogunremi Tuesday, September 15, 2009 12:25 PM added MSDN link
    Tuesday, September 15, 2009 11:55 AM
  • There shouldn't be any memory leak. List<T> has been used for years by thousands of developers and personally by me :).
    My opinion is that some other object keeps reference to your list (maybe some peace of code called ToArray method and keeps this array alive). This is the only possible IMHO explanation here.

    Vitaliy Liptchinsky http://dotnetframeworkplanet.blogspot.com/
    • Proposed as answer by eryang Monday, September 21, 2009 7:25 AM
    • Marked as answer by eryang Thursday, September 24, 2009 1:49 AM
    Tuesday, September 15, 2009 12:45 PM
  • No, you cannot expect Private Bytes to change.  The internal array used by List<> is probably large so it would be stored in the Large Object Heap.  It takes a gen #2 collection to get it released.  The List<> object itself is very small.

    Hans Passant.
    Tuesday, September 15, 2009 2:55 PM
    Moderator
  • Hi Cavin,
    The case may caused by two reasons:
    1. When invoke ToArray() method of a List<T>, a new T[] will be created and its values are copied from the List<T>, so, even if the List<T> is GCed, the new T[] still alive. Just as Vitaliy said, review your code to find out ToArray operations.
    2. If size of the inner T[] is big enough, it will be allocated at the Large Object Heap (LOH). since GC on generation 0 is more frequent than on LOH, the situation (the inner T[] still alive but the List<T> has been GCed) can happen. In this condition, I don't think it is a memory leak, it is just because the size of objects on LOH haven't reach threshold, so the GC on LOH is not triggered.

    Thanks,
    Eric


    Please remember to mark helpful replies as answers and unmark them if they provide no help.
    • Marked as answer by eryang Thursday, September 24, 2009 1:49 AM
    Monday, September 21, 2009 9:55 AM