Search code examples
c#memory-managementpointersobjectobject-reference

Is there a good way to perform WPF/C# object dereferencing, for garbage collection?


Application Background

Our platform is a click-once WPF application. We have a "shell" that contains a navigation menu structure and it hosts our own custom "page" classes. When you navigate to a new page, we swap out the content of the shell (essentially).

Problem

So, I work for a company that is working on a extremely large software project. We have much code that we found memory issues with.

The problem is that there are plenty of places in our application were events are wired and never unwired. I'm not sure why developers were doing this, I'm guessing that they expected the objects to get cleaned up each time a user navigates to a new "page".

We don't have the option of refactoring every page (in this release). Is there a way with C# to remove all references from an object? (Therefore allowing the garbage collector to throw that object away, along with all of it's internal references)

We are trying to get this memory back, but it is quite complicated to find objects are still referencing our pages (object references), when we have WPF to deal with.

We have looked at the visual and logical trees and used profiling applications to help us to manually clean things up (for proving out the idea) and this proved to be extremely hard as well.

I sat back and thought, why are we doing all this work to find object references, can't we just "dereference" this "page" when it is closed?

Which brings me here :)
Any help is greatly appreciated!


UPDATE 1

In the comments the following was asked:

Q: Does the app. actually have memory problems? How are these exhibited/detected? Or is this memory hanging around until a GC2 happens? – Mitch Wheat

A: It has memory problems. If we leave a page (property that holds the page gets set to a new object) the old object never gets collected by the garbage collector. So memory just keeps on growing. If our company started over, with this application. The first thing we should look at would be implementing WeakEvent Patterns and using more Routed Commands in WPF.

UPDATE 2

I was able to come up with my own solution.


Solution

  • I implemented WeakEvents to solve this issue.

    Unfortunately, Microsoft recommends that you use their WeakEventManager as a base class and create a manager type for EACH event in your application!!! I tried to write a manager that inherits from this base and get it to be more "generic" (not in the C# term for generic). This "common" Event manager was not possible with Microsoft's base class. I had to write a Event manager from scratch.

    Thank you for any help posted to this question.