Garbage collector question

D

DoB

Hi,

Suppose a situation where some object goes out of scope and its reference
is not kept anywhere, but a reference to some delegate (that references
one of the object's methods) is kept as a value in some map.

Is there a possibility that the object is disposed and the delegate will
be invalid?

Yours DoB
 
J

Jon Skeet [C# MVP]

Suppose a situation where some object goes out of scope and its reference
is not kept anywhere, but a reference to some delegate (that references
one of the object's methods) is kept as a value in some map.

Is there a possibility that the object is disposed and the delegate will
be invalid?

Well, it might be disposed - but it certainly won't be garbage
collected.

The "a reference to a delegate that references one of the object's
methods" is directly contradictory to "its reference is not kept
anywhere". The reference *is* kept in the delegate - provided it's an
instance method, of course.

Jon
 
D

DoB

The "a reference to a delegate that references one of the object's
methods" is directly contradictory to "its reference is not kept
anywhere". The reference *is* kept in the delegate - provided it's an
instance method, of course.

Yes, it will be an instance method.

So...
as long as the reference to the delegate is kept, the referenced method
might be safely invoked, is that right?

DoB
 
M

Marc Gravell

Define "safely" ;-p

The delegate will prevent the object being garbage collected, but if
the object itself has been deliberately closed/disposed/whatever (by
code that thinks the object is no longer needed) then the method will
probably throw an exception when invoked.

This type of delegate (to an otherwise unreferenced object) is fine by
itself, but be aware that if used inappropriately this type of hanging
reference (especially events) is a common cause of memory issues -
i.e. event subscriptions keeping thousands of objects from being
collected. For example:
http://www.codeproject.com/KB/showcase/IfOnlyWedUsedANTSProfiler.aspx

Marc
 
R

Rene

If you look at the Delegate definition, you will see that it contains a
"Target" and a "Method" properties.

public object Target { get; }
public MethodInfo Method { get; }

This "Target" property is used by the delegate to hold a reference to the
object that contains the "Method" that should be called when the delegate is
invoked.

Having said that, as long as the "Target" property is pointing to the object
(call this object XYZ), the object XYZ will never be garaged collected
because there *is* a reference to this object (XYZ) in the delegate
instance.

It may look like there is no way to get a hold of the XYZ object but you
could do so by using the "GetInvocationList()" method of the delegate.
 
D

DoB

Define "safely" ;-p

:)))

In principle I assumed that whenever we explicitly make the object unusable
(closed/disposed... whatever), we will also explicitly remove the delegates
from the map in question.
I was not sure about what would happen in implicit cases, specifically
including the case when the object in question goes out of scope. I could
also think of such situations like power management issues, etc. i.e.
situations not caused directly via our code.

This type of delegate (to an otherwise unreferenced object) is fine by
itself, but be aware that if used inappropriately this type of hanging
reference (especially events) is a common cause of memory issues -
i.e. event subscriptions keeping thousands of objects from being
collected. For example:
http://www.codeproject.com/KB/showcase/IfOnlyWedUsedANTSProfiler.aspx

In fact we also want to implement an event subscription mechanism ;-), so we
take the same risk. Of course we assume that all event subscriptions will be
deleted each time we explicitly make the subscribed object unusable. It
would be nice to automatise it somehow, so that the programmer does not have
to think too much about it every time the object gets explicitly disposed.
The problem is that I do not know how to use inheritance for this, because
the objects' classes are going to inherit various other business logic
classes...

If you possibly know about a description of some nice event subscription
mechanism, please let me know ;-)

Yours
DoB.
 
J

Jon Skeet [C# MVP]

:)))

In principle I assumed that whenever we explicitly make the object unusable
(closed/disposed... whatever), we will also explicitly remove the delegates
from the map in question.
I was not sure about what would happen in implicit cases, specifically
including the case when the object in question goes out of scope. I could
also think of such situations like power management issues, etc. i.e.
situations not caused directly via our code.

If you keep track of what you've subscribed to, you could make the
Dispose method unsubscribe as well. It's a bit icky though - I'd
prefer to design round it usually.

Jon
 
D

DoB

If you keep track of what you've subscribed to, you could make the
Dispose method unsubscribe as well.

What I've actually coded is a typical mediator pattern - various objects
subscribe as listeners to varoius events to a mediator (a singleton).
The mediator can unsubscribe all subscriptions made by a particular object
in a single method call.
The problem arises if this method is not called after an object is no longer
needed - either because of programmer forgot to call it, or because of some
unpredicted execution path.

It's a bit icky though - I'd
prefer to design round it usually.

What do you mean?

Yours
DoB
 
J

Jon Skeet [C# MVP]

What I've actually coded is a typical mediator pattern - various objects
subscribe as listeners to varoius events to a mediator (a singleton).
The mediator can unsubscribe all subscriptions made by a particular object
in a single method call.
The problem arises if this method is not called after an object is no longer
needed - either because of programmer forgot to call it, or because of some
unpredicted execution path.

Well, you *could* use a finalizer to unregister; alternatively, use
WeakReference in the mediator. Either way, you should certainly log
the situation where you've failed to unsubscribe when you should have
done.
What do you mean?

There are often design choices which allow the relationship to be
reversed somehow, but that may not be the case in your situation - or
there may be oteher undesirable consequences.

Jon
 
S

Scott Roberts

What I've actually coded is a typical mediator pattern - various objects
subscribe as listeners to varoius events to a mediator (a singleton).
The mediator can unsubscribe all subscriptions made by a particular object
in a single method call.
The problem arises if this method is not called after an object is no
longer needed - either because of programmer forgot to call it, or because
of some unpredicted execution path.

I only caught the tail end of this thread, so sorry if this has already been
mentioned.

It looks like you're having trouble with memory leaks resulting from event
delegates. If so, this link may be useful:
http://diditwith.net/2007/03/23/SolvingTheProblemWithEventsWeakEventHandlers.aspx
 
M

Martin Carpella

Hi,

Jon Skeet said:
Well, you *could* use a finalizer to unregister;

How does the finalizer come into play here? The subscriber won't be
finalized as there are still references to it from the event source.
And if the event source is garbage collected, its references to the
subscriber don't exist any more.

Could you elaborate on this?

Best regards,
Martin
 
J

Jon Skeet [C# MVP]

Martin Carpella said:
How does the finalizer come into play here? The subscriber won't be
finalized as there are still references to it from the event source.
And if the event source is garbage collected, its references to the
subscriber don't exist any more.

Could you elaborate on this?

Yes, of course you're absolutely right - I can't immediately say what I
was thinking of...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top