5

I'm having an awful time with C# not freeing up memory for a large structure I'm holding in memory after I'm no longer referencing it.

I've included some code below that showcases a similar problem to the one I'm having. I think I must be misunderstanding something about the GC because I'm not sure why the following code would throw an Out of Memory Exception.

Does anyone know why the code I've included would throw out of memory? None of the lists are being held and they are immediately available to be cleaned up.

Thanks,

Paul

Repro: brand new 4.5 console application, paste the code into Main.

Exception will be thrown on the third "new List", in the first iteration of the for loop. If the for loop is omitted, the OOM will not occur.

for (var i = 0; i < 100; i++)
{
    new List<int>(100 * 1000 * 1000);
    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true);
    new List<int>(100 * 1000 * 1000);
    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true);
    new List<int>(100 * 1000 * 1000);
    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true);
    new List<int>(100 * 1000 * 1000);
    GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true);
}
skippy10110
  • 145
  • 1
  • 4
  • 9
  • In your real program, are you using GC? you should try to allow the program to do its own gc if possible – Sayse Jul 10 '13 at 19:06
  • Just my opinion here, but if you need to do a lot of granular memory management and GC, C# may not be the right tool for the job. Something like C/C++ might be a better fit. – Gray Jul 10 '13 at 19:07
  • Which of these lines throws the exception? The first or another? – Sebastian Negraszus Jul 10 '13 at 19:08
  • I cannot repro the problem with the code above. – Brian Rasmussen Jul 10 '13 at 19:08
  • In my real program I've tried forcing GC, but it doesn't help. I would rather work with the GC and not force collections, even if it did work. The actual class I'm using is ImmutableDictionary from here: https://nuget.org/packages/Microsoft.Bcl.Immutable/ – skippy10110 Jul 10 '13 at 19:09
  • For me it's throwing on the third "new List"... if you copy and paste a few more times, do you still not get the exception? – skippy10110 Jul 10 '13 at 19:09
  • I can't reproduce this. Please list target Fx, Fx version, OS and hardware. And make sure the actual code produces the error. – H H Jul 10 '13 at 19:11
  • I updated my question, it seems that the for loop is what triggers the error, even though it never gets to a second iteration. – skippy10110 Jul 10 '13 at 19:21
  • What's all the `GC.Collect` code in there for? Why can't you just let the garbage collector work on its own terms? – Cody Gray - on strike Jul 10 '13 at 19:25
  • I want to let it work on its own terms. :) However, it's not. You can remove the GC.Collect and it'll still error out. – skippy10110 Jul 10 '13 at 19:27

1 Answers1

4

OK, this does reproduce but only under the following conditions:

  • Fx 4.5, Platform = Any CPU, configuration = Debug .

By selecting either x64 platform or Release mode the program runs as expected.

So, tentative conclusion: with no-optimization the List<>s remain rooted where they shouldn't be. And so the GC calls have no effect at all and the x86 memory space is quickly exhausted.

This may be a bug or it might a 'feature' aimed at debugging.

But while there does seem to be a problem it is very easily avoided.

H H
  • 263,252
  • 30
  • 330
  • 514
  • I'm still getting the error even with release mode selected, unfortunately. – skippy10110 Jul 10 '13 at 19:46
  • To be sure, is []optimize checked? – H H Jul 10 '13 at 20:03
  • I believe that this is in fact a "feature" related to debugging, but Im not 100% sure of that. I read a great SO answer which, I recall, explained something similar to this not long ago, I'll try to find it (actually, I initially thought that you wrote the response. Perhaps not.) Of course, if the OP is correct and it occurs in an optimized build... this is wrong. – Ed S. Jul 10 '13 at 21:19
  • I think it was Hans, he linked to the dupe. – H H Jul 11 '13 at 11:36
  • I don't have optimize checked, I'm not sure why my release build would be acting differently. For my actual program I think I just need to accept that I'll need to run in 64-bit mode. – skippy10110 Jul 12 '13 at 13:05
  • Read the answer in the linked dupe, quite informative. – H H Jul 12 '13 at 15:40
  • I did take a quick look at that, I'll look again tonight. Thanks for the link and the help! – skippy10110 Jul 12 '13 at 16:56