varun
varun

Reputation: 11

Trying to find memory leak if it exists for a GUI application

I have a very simple GUI application that runs HIL tests for a system. I select a test from a combo box, then click run. This starts the test and runs for 27 minutes. During this time, the CPU is capturing data and storing the data in String Builder. When the test is done, the string builder writes the captured data to a file. I ran the same test 3 times to check for memory leaks. Please look at the attached picture.

Snapshot#1: Start of the GUI Snapshot#19: End of the first try SnapShot#33: End of the second try Snapshot#38: End of the third try

if we compare 33 and 38, we can see that the objects and heap size are the same which leads me to believe that there is no memory leak.

but if we compare 19 and 33/38, we can see that the no of objects increased by 1 and the heap size increased by 0.1KB which leads me to believe that there is a small memory leak.

If we compare 1 with the others, we see that the no of objects and the heap size increased quite a bit relatively speaking.

So my question is, is there a memory leak here? How do I come to a solid conclusion?

Snapshots

Diagnotic session1

Diagnostic Session2

Upvotes: 0

Views: 444

Answers (1)

Thomas Weller
Thomas Weller

Reputation: 59238

C# uses a concept of garbage collection (GC), which means that objects are not freed at the end of a scope but some arbitrary time after that, which can be seconds or even minutes.

In your tool a GC run it is indicated by a small yellow tickmark at the top of the memory bar.

GC tickmark

As you can see, only one garbage collection happened about at about 37:00 in time (which is ~2200 seconds).

So my question is, is there a memory leak here?

At the moment it's too little data to say for sure.

How do I come to a solid conclusion?

  1. You need a tool that is .NET specific, i.e. it knows that .NET is garbage collected and will perform a garbage collection before measuring. E.g. Jetbrains dotMemory (part of Resharper).

  2. Setup everything for measuring

  3. Run the test sequence once. This will ensure that DLLs are loaded, static stuff is initialized, lazy loading stuff has been loaded etc.

  4. Take a snapshot

  5. Run the test sequence 5 times (use a prime number)

  6. Take a snapshot again

  7. Run the test sequence 7 times (use a prime number)

  8. Analyze the differences between snapshots.

    Any leak typically leaks 5 times during the first run and 7 times during the second run or a multiple of that. You can hardly leak 2 objects in 7 runs if all runs are identical (could happen with a lot of ifs; make sure each run does the same thing).

    If you have such a leak, do a code review to check where it's gonna be freed.

Potential false positives:

  • caches

  • log files or similar which are appended to during the whole test sequence

Note: In Visual Studio, don't just use the diagnostic tool that automatically runs when you start debugging. Instead, use Debug / Performance Profiler and choose "Memory usage"

Performance Profiler memory usage

That one allows you to force a GC and take a snapshot.

Force GC

Upvotes: 0

Related Questions