|
| Author |
Message |
DoB
Joined: 11 Dec 2007 Posts: 1
|
Posted: Tue Dec 11, 2007 6:58 pm Post subject: Garbage collector question |
|
|
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
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
Archived from group: microsoft>public>dotnet>languages>csharp |
|
| Back to top |
|
 |
Jon Skeet [C# MVP]
Joined: 08 Aug 2007 Posts: 27
|
Posted: Tue Dec 11, 2007 10:03 am Post subject: Re: Garbage collector question |
|
|
On Dec 11, 12:58 pm, DoB wrote:
> 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 |
|
| Back to top |
|
 |
DoB
Joined: 11 Dec 2007 Posts: 4
|
Posted: Tue Dec 11, 2007 7:40 pm Post subject: Re: Garbage collector question |
|
|
> 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 |
|
| Back to top |
|
 |
Marc Gravell
Joined: 08 Aug 2007 Posts: 20
|
Posted: Tue Dec 11, 2007 11:12 am Post subject: Re: Garbage collector question |
|
|
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 |
|
| Back to top |
|
 |
Rene
Joined: 11 Aug 2007 Posts: 5
|
Posted: Tue Dec 11, 2007 1:47 pm Post subject: Re: Garbage collector question |
|
|
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.
"DoB" wrote in message @dwroblewski.hq.abg.com.pl...
> 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
>
> --
> Using Opera's revolutionary e-mail client: http://www.opera.com/mail/ |
|
| Back to top |
|
 |
DoB
Joined: 11 Dec 2007 Posts: 4
|
Posted: Wed Dec 12, 2007 4:38 pm Post subject: Re: Garbage collector question |
|
|
> 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. |
|
| Back to top |
|
 |
Jon Skeet [C# MVP]
Joined: 08 Aug 2007 Posts: 27
|
Posted: Wed Dec 12, 2007 8:39 am Post subject: Re: Garbage collector question |
|
|
On Dec 12, 10:38 am, "DoB" wrote:
> > 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.
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 |
|
| Back to top |
|
 |
DoB
Joined: 11 Dec 2007 Posts: 4
|
Posted: Thu Dec 13, 2007 6:58 pm Post subject: Re: Garbage collector question |
|
|
> 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 |
|
| Back to top |
|
 |
Jon Skeet [C# MVP]
Joined: 08 Aug 2007 Posts: 27
|
Posted: Thu Dec 13, 2007 10:08 am Post subject: Re: Garbage collector question |
|
|
On Dec 13, 12:58 pm, "DoB" wrote:
> > 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.
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.
> > It's a bit icky though - I'd
> > prefer to design round it usually.
>
> 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 |
|
| Back to top |
|
 |
Scott Roberts
Joined: 15 Nov 2007 Posts: 23
|
Posted: Thu Dec 13, 2007 2:39 pm Post subject: Re: Garbage collector question |
|
|
>> 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.
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 |
|
| Back to top |
|
 |
Martin Carpella
Joined: 08 Aug 2007 Posts: 2
|
Posted: Fri Dec 14, 2007 6:49 pm Post subject: Re: Garbage collector question |
|
|
Hi,
"Jon Skeet [C# MVP]" writes:
> 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 |
|
| Back to top |
|
 |
Jon Skeet [C# MVP]
Joined: 08 Aug 2007 Posts: 266
|
Posted: Fri Dec 14, 2007 10:48 pm Post subject: Re: Garbage collector question |
|
|
Martin Carpella wrote:
> "Jon Skeet [C# MVP]" writes:
>
> > 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?
Yes, of course you're absolutely right - I can't immediately say what I
was thinking of...
--
Jon Skeet -
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
|
|
| Back to top |
|
 |
|