2

When the memory dump is being analyzed, it shows that this particular string variable which is holding the xml content is causing memory leak. I read on some of the articles that LoH goes to Gen 2. So,

  1. Will garbage collector gets invoked if Gen 0 and Gen 1 is not under pressure and Gen 2 is under pressure due to LoH ?
  2. Will it go to Gen 2 when it has released Gen 0 or Gen 1 memory ?
  3. If so what’s the better way to handle this ?
Sudheesh P
  • 29
  • 1
  • 3
  • Is LoH the Large Object Heap? Do include the framework version for questions involving the GC and attempts made to find out more information on this. – DL Narasimhan Mar 21 '16 at 07:09
  • Do include a link to the article you read as well – DL Narasimhan Mar 21 '16 at 07:10
  • Is there a reference to that string? Is it perhaps interned? – Luaan Mar 21 '16 at 07:11
  • Tried on all .Net versions from 2.0 to 4.6. The instance that holds this string has been set of null also. – Sudheesh P Mar 21 '16 at 07:19
  • 2
    It is not that simple, a program that *only* allocates large objects (>= 85000 bytes) still runs the garbage collector even though it only ever allocates LOH objects. Clearly the info you provided does not give anybody a decent shot at guessing why this large string isn't getting collected, you'll have to work on repro code. – Hans Passant Mar 21 '16 at 08:03
  • Get a memory profiler designed for .NET and see what holds this string in memory – Ed Pavlov Mar 22 '16 at 21:03

2 Answers2

0
  1. No, it will not
  2. Only if there's enough memory pressure

However, if your application is doing allocations, it's pretty unlikely the string will survive for too long. And if there's not enough memory pressure, the GC has little reason to release the memory.

Do make sure the string is not referenced anymore, though. Count the references, check that it's not interned.

You can force a garbage collection, but it's great way to damage GC performance. It might be the best solution for your case if your application does the odd "allocate a huge string and then forget it" operation, and you care about memory available to the rest of the system (there's no benefit to your application). There's no point in trying that if you're doing a lot of allocations anyway, though - in that case, look for memory leaks on your side. WinDbg can help.

Luaan
  • 62,244
  • 7
  • 97
  • 116
  • I have used WinDbg to analyze. 1. String is not interned. – Sudheesh P Mar 21 '16 at 07:22
  • Slight modification to my Question 1 Will garbage collector gets invoked if Gen 0 and Gen 1 is not under pressure and Gen 2 is under pressure due to LoH ? – Sudheesh P Mar 21 '16 at 07:23
  • @SudheeshP There's no such thing, so no, it will not. That's kind of the point of having the generational heaps in the first place. And AFAIK, the limits (and allocation thresholds) for each of the generations increase if you require a lot of memory overall, though I'm not sure if this also applies for "one big thing on LOH". In the end, avoiding allocating such a huge string might be your best approach anyway (most APIs allow for streaming). Also, why do you care if the memory is released? Are you having issues, or are you just scared of the big number in task manager? – Luaan Mar 21 '16 at 08:21
  • The memory grows and finally the application crashes – Sudheesh P Mar 21 '16 at 09:01
  • @SudheeshP Okay, so the string must be referenced somewhere (unless you're simply trying to allocate a string that has no place to go - like a 2 GiB string or something in a 32-bit process). How did you check there are no references to the string? – Luaan Mar 21 '16 at 09:06
  • @SudheeshP And there are no roots at all? Are you using the full memory dump? And when you check after the next operation (e.g. the next file processing), the original string still remains? Do you have a dump from the crash? Have you checked the heap fragmentation? – Luaan Mar 21 '16 at 09:44
0

1. Will garbage collector gets invoked if Gen 0 and Gen 1 is not under pressure ? If there is enough space in Generation0 and Generation2, then Garbage Collector will not be invoked.

If there is enough space in Generation0 and Generation2, then it means that that there is enough space to create new objects and there is no reason to run Garabage Collection.

2. Will it go to Gen 2 when it has released Gen 0 or Gen 1 memory ?

If the object is survived after Garbage Collection in Generation1 and in the Generation1, then the object will be moved to Generation2.

3. If so what’s the better way to handle this ?

  • To destroy an object from heap, you should just delete references of this string. Your string variable which has xml values should not be static to be garbage collected.(read more about roots)

  • Try to use compact GCSettings.LargeObjectHeapCompactionMode:

    GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GC.Collect();

This will compact the Large Object Heap when the next Full Garbage Collection is executed. With GC.Collect() call after the settings been applied, the GC gets compacted immediately.

  • Try to use WeakReference:

    WeakReference w = new WeakReference(MyLargeObject); MyLargeObject = w.Target as MyLargeClass;

    MyLargeClass MyLargeObject;
    if ( (w == null) || ( (MyLargeObject=w.Target as MyLargeClass) == null) ) { MyLargeObject = new MyLargeClass(); w = new WeakReference(MyLargeObject); }

This article gives is very useful to you about Garbage Collection and the article is written in plain English.

Community
  • 1
  • 1
StepUp
  • 36,391
  • 15
  • 88
  • 148