0

I have a WPF desktop application that loads a very large serialised object from file and performs some data processing on it. Once finished, the user can discard this data and load another file for processing, and so on. As a precaution, due to the size of the objects being created, I compact the large object heap after each "run" using:-

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

For interest, I'm displaying memory usage on the app's window using GC.GetTotalMemory(false). After loading and processing the first file, memory usage jumps to 2.2Gb (yes the data is that big). If I then process the same file again, memory usage jumps to 4.4Gb, suggesting the previous data isn't being freed/disposed (although I am 99.99% certain that it should be).

Anyway, here's the strange thing. If I run the app using the VS2019 performance profiler in "memory usage" mode, I can see its chart ramp up to 2.2Gb on the first processing run, then to 4.4Gb on the second. But, if I then take a snapshot, memory usage at that moment drops to 2.2Gb on both the profiler chart and the value displayed in my app.

If I don't use the performance profiler (or do but not take a snapshot), the memory usage displayed in my app remains at 4.4Gb and never drops. Why would the profiler (or more specifically, taking a snapshot) be having an effect on memory usage?

enter image description here

Andrew Stephens
  • 9,413
  • 6
  • 76
  • 152
  • It more likely has an impact on how the memory usage is being reported. – Kuba hasn't forgotten Monica Mar 20 '20 at 15:10
  • Feature, not a bug. [Relevant phrase](https://devblogs.microsoft.com/devops/diagnosing-memory-issues-with-the-new-memory-usage-tool-in-visual-studio/) is "causes CLR to do a GC". The snapshot can only show rooted objects, you'd have a very hard time figuring out how the objects in that list matches the memory usage without a collection first. – Hans Passant Mar 20 '20 at 16:21
  • @HansPassant why is it that the GC being done in my code not having an effect? What is the profiler doing differently? – Andrew Stephens Mar 22 '20 at 08:29
  • 1
    Nothing, just one more GC.Collect() call. I can't see where you put it, [it matters](https://stackoverflow.com/a/17131389/17034) when you profile the Debug build. – Hans Passant Mar 22 '20 at 11:09

1 Answers1

0

Memory profilers typically run the garbage collector before collecting the memory snapshot. This is probably what you are observing. The GC will typically only run "when needed", especially for full collections that are more expensive to run.

So the observed behavior does not necessarily indicate any problem.

JonasH
  • 28,608
  • 2
  • 10
  • 23