Something is blocking my memory, and the program freezes on GC.Collect () or GC.GetTotalAmountOfMemory (true)

whenever I call GC.Collect() or GC.GetTotalAmountOfMemory(true) , the whole program just freezes. Now I know what you will say: do not call GC.Collect() , GC takes care of itself. The problem is that this is not in my case, something is hanging in memory, and the GC cannot get rid of it.

I have no idea what it could be (a large / old project). I hope someone knows how to get information about what the GC is trying to do (and obviously cannot), so that I can look for a problem, or if something like a memory profiler might be useful here (I have have ANTS currently installed) and what should I look for.

* edit something that I completely forgot: sometimes, when I call one of the two GC methods, memory usage increases by ~ 10 kilobytes / second

* edit2 I have to fix myself: GC.Collect () works fine. Only GC.GetTotalMemory (true) is executed. GC.GetTotalMemory (false) works fine too.

* Edit3 and yup, as some of you have said: It seems to be a finalizer somewhere. When I run WaitForPendingFinalizers (), it just sits there, doing nothing. Strike>

ok, now I'm completely confused: when I entered GC.GetTotalMemor(true) or GC.WaitForPendingFinalizers() in the nearest Visual Studio window after I paused the debugger, the program freezes (which I did all the time ... Now I feel stupid ) When I add it to my regular source code and compile it, it works great.

Sorry for all the fuzz, there seems to be another reason for memoryleak.

+4
source share
2 answers

Do you redefine any finalizers? When the finalizer does not return (maybe you wait at any time for another thread), the application may freeze. GC.Collect() calls the finalizer, but it never returns, since it expects the finalizer to return. This could cause a memory leak because the GC cannot complete garbage collection.

Decision

You should be able to debug it when the GC collects and you press "pause", it should show the stack trace where it hangs. If everything goes wrong, maybe you need to check the disassembly where your application hangs.

GetTotalMemory (true)

This method forces the garbage collection, so it is the same as GC.Collect() .

Update

Let's take a look at GetTotalMemory:

 public static long GetTotalMemory(bool forceFullCollection) { long totalMemory = GC.GetTotalMemory(); if (!forceFullCollection) { return totalMemory; } int remainingSteps = 20; long lastMemory = totalMemory; float num4; do { GC.WaitForPendingFinalizers(); GC.Collect(); totalMemory = lastMemory; lastMemory = GC.GetTotalMemory(); num4 = (float)(lastMemory - totalMemory) / (float)totalMemory; } while (remainingSteps-- > 0 && (-0.05 >= (double)num4 || (double)num4 >= 0.05)); return lastMemory; } 

As you can see, GetTotalMemory expects finalizers, so it should be a finalizer, a hovering application. GC.Collect() is called when finalizers are finished and will never be called because they never pass a string before.

At any point in your application (unsafe code? Another thread?) There is something that allocates a lot of memory, while the GC never has the ability to clear existing memory.

Renouncement

This is a pure assumption, I don’t know if the GC handles such situations, but I think that it cannot break the finalizer, because it can take a lot of time, and the GC does not know if it just hangs or still finishes.

+6
source

Did you consider that you are using server mode GC settings, so that one GC thread runs on the processor core?
Did you investigate the problem using performance counters, landfills or profilers? The ANTS profile profiler is very useful if the application itself does not slow down too much using it.
I will also look at your application using Windows Process Explorer to get an idea of ​​what is happening on the memory side.

+2
source

Source: https://habr.com/ru/post/1401359/


All Articles