Anthony Nichols
Anthony Nichols

Reputation: 1668

Determine if Object has been destroyed (i.e no longer found anywhere) in C#

I'm sure this has been asked before and I just don't know the right terms to search for. In a C# program I am working on I have an List that keeps track of Objects. Those objects can also be displayed on the screen via references by other objects.

Sometimes after an object is removed from the list it is still temporarily available to those other objects (as it should be)... After those objects are done however I want to make sure the object is 100% gone and not staying in memory still being referenced by a forgotten object... How can I do this?

To be clear, this doesn't need to happen as part of the shipped program, only for debugging.

Upvotes: 3

Views: 3882

Answers (3)

Denis Palnitsky
Denis Palnitsky

Reputation: 18387

I guess you need this for testing purpose. In such case I would recommend to use memory profiler such as ANTS Memory Profiler or JetBrains dotTrace. You can find more complete list of profilers here

Upvotes: 2

David
David

Reputation: 10708

You normally can't. The GC is meant to take care of memory management behind the scenes, and does it's job very specifically and by means best not trifled with. In particular, other parts of your code may keep a reference to the item you want removed, which SHOULD prevent its collection. such is the nature of memory managed languages such as C#.

That being said, however, there are a few ways to check for when an object is disposed. The easiest to to create a simple destructor and breakpoint it, allowing you to "see" whenever an object is collected.

~MyClass()
{ // Breakpoint here
}

The other way is to make a static list of WeakReferences to your objects, which each object subscribes to when it's created. Make sure to keep that other list, however, as a weak reference is specifically designed to allow garbage collection, allowing you to track an object to its destruction. The other list is necessary to keep the objects alive. Also note that in .NET 4.5, there is a generic version of WeakReference. EDIT: This is definitely the solution I recommend after seeing the updates to your question. You can also quickly query which objects are still being refernced via Linq

var leftoverObjects = WeakCache
    .Select(wr => wr.Target)
    .OfType<MyObject>() // Only if you're not using that Generic Weak Reference
    .Except(ObjectList); // filters away objects in the List

Be warned the above query creates a result which has strong references, so once run, it'll keep those objects in memory as long as the result is referenced.

If you have some sort of unmanaged memory backing your object, that's exactly what the IDisposable interface is designed for.

UPDATE: finally, if you MUST do so, you can Force the GC to Collect. This is often heavily advised against, as you start to warp the Generations that help optimize the GC in the first place.

Upvotes: 4

Guffa
Guffa

Reputation: 700422

There is no easy way to look for an object reference "backwards", basically you would need to use reflection to loop through all objects and structs that exist in the application and check all references. You just have to make sure that all code that uses the reference really removes it when they are done.

One way to check if there seems to be any live references (but not where they are) is to keep a list of weak references to the objects that you don't use any more. The weak references will not keep the objects from being collected, but you can use them to check if the objects have been collected or not.

As there is no guarantee that an object should be collected within any certain time, you can never know for sure if it's an actual reference that keeps an object alive, but the longer the objects survive, the more likely it is that you have a reference to it somewhere.

Upvotes: 0

Related Questions