[.net] Garbage Collector question

This topic is 3588 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi Is there a way to associate the lifetime of one object with the other's without making an explicit strong reference? This is what I mean:
object objA = new object();
object objB = new object();

objB.keepAReference = objA;
objA = null;

GC.Collect();
// here objB and objA are both alive


The problem is that objB doesn't really have a field "keepAReference". So I can only write this:
object objA = new object();
object objB = new object();

objA = null;

GC.Collect();
// here objB lives and objA is dead


I know that this example seems a bit artificial, but when you realise that there can be WeakReferences somewhere it could be quite usefull. So is there a way to prevent collection of objA? Some magic "GC.AssociateObjectLifetime(objA, objB)" or "GC.ListenToCollection(objB)"? (Oh, one more thing: I can't keep reference to objA anywhere else - cause I need it to live when objB lives, and die when it dies.) zbychs

Share on other sites
You don't want to design that way. You cannot force/guarantee death in C#. Give us the actual example for the actual problem you have. We can better help you then.

I suspect some sort of A.Close() -> A.OnClose() -> B.Close() mechanism is the likely result.

Share on other sites
Quote:
 Original post by TelastynYou don't want to design that way. You cannot force/guarantee death in C#. Give us the actual example for the actual problem you have. We can better help you then.

I'am designing this way cause what I'm doing can be pretty low level/hacky.
I am writing a component platform, that is a system that manages creation, destruction, dependency injection and connections between components. I want my components to be "Plain Old C# Objects", so I can't really add any extra info to them. I just wan't to analyze them using attributes and reflection and then create an ComponenetEnvironment object that would serve as an invisible mediator during communication between components. The environments would be held by a global registry, that would enable look up of an environment for a given component. This registry could not hold those environments via strong references, cause they need to be garbage collected when the component dies. So I need to attach environment's lifetime to the lifetime of the component.

Now I know that there are other solutions, like creating an IComponent interface, and that a global registry is not always a good idea, etc. But the hard constraint is that components need to be POC#O's (by design).

I'm starting to doubt it, but is this even possible?

zbychs

Share on other sites
Depending on the usage pattern, WeakReferences with some sort of self-destruct when the mediator detects death of its charges might be suitable. Though WeakReferences are kinda sucky.

Share on other sites
Yes it is possible. Is it a good idea? Well not really.

What you are looking for to disable garbage collection is GC.SuppressFinalize(object) and to put it back into garbage collection GC.ReRegisterForFinalize(object).

theTroll

Share on other sites
Quote:
 Original post by TheTrollYes it is possible. Is it a good idea? Well not really.What you are looking for to disable garbage collection is GC.SuppressFinalize(object) and to put it back into garbage collection GC.ReRegisterForFinalize(object).theTroll

No, not really. SuppressFinalize and ReRegisterForFinalize only deal with finalization of objects. They will still be garbage collected.

Share on other sites
Quote:
 Original post by TelastynDepending on the usage pattern, WeakReferences with some sort of self-destruct when the mediator detects death of its charges might be suitable. Though WeakReferences are kinda sucky.

This "detects death of its charges" is the tricky part :)
Besides the catch is, that if a mediator is held only by WeakReferences - it will get collected. And if there would be a strong reference to it somewhere besides the "owner" object, the owner might never get collected *if* mediator would hold a strong reference to it's owner in any way, like this:
mediatorA is managing objA
objB has a srong reference to objA
mediatorA references objB, not necessary directly

In other words, to avoid memory leaks one would have to ensure that mediatorA *never* references objA strongly, even indirectly.
And this constraint is impossible to ensure (in my application at least).

So the only way I see would be either an event "objA has been collected" or a rule "don't collect mediatorA until objA gets collected". (That last thing is easy - just make a reference from objA to mediatorA - but not an option with POC#O).

Since there doesn't seem to be a solution to this problem I would just have to find some other way to manage communication between components. One that would work with POC#Os.

zbychs

Share on other sites
Quote:
Original post by Zbychs
Quote:
 Original post by TelastynDepending on the usage pattern, WeakReferences with some sort of self-destruct when the mediator detects death of its charges might be suitable. Though WeakReferences are kinda sucky.

This "detects death of its charges" is the tricky part :)

No so much.

// mediator//     void mediate(){           if(!WeakReferenceToObject.IsAlive){               // do mediator cleanup.           }

Which presumes you don't need to know immediately when something dies, only when the mediator tries to deal with it. (and perhaps also that the mediator is triggered relatively frequently)

Quote:
 Besides the catch is, that if a mediator is held only by WeakReferences - it will get collected.

Which seems backwards to me. The mediator should hold the WeakRef's to its targets. Especially since there's the constraint that the targets must not know about this mediator construct. Make your class' "knowledge" into a tree and things become much simpiler.

• 10
• 17
• 9
• 13
• 41