Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
475 views
in Technique[技术] by (71.8m points)

c# - Why garbage collector takes objects in the wrong order?

I have an application with two classes, A and B. The class A has inside a reference to class B. The destructors of the classes do some cleanup of resources but they have to be called in the right order, first the destructor of A and then the destructor of B.

What is happening is that somehow the destructor of B is called first and then the destructor of A is crashing because is trying to execute methods from a disposed object.

Is this behavior of the GC correct? I expected the GC to detect that A has a reference to B and then call the A destructor first. Am I right?

Thanks mates!

PD: In case of doubt about destructor/finalizer/disposer etc that's what we have:

~A()
{
    this.Dispose();
}

~B()
{
    this.Dispose();
}    
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As others have noted, your finalizers are wrong, wrong, wrong. You cannot simply call Dispose in a finalizer and expect good things to happen. Read up on the correct way to implement the disposable pattern.

Getting that right is the beginning, not the end, of the work you have to do. In addition to all the other correct answers here, I note that:

  • the finalizer can (and usually does) run on a different thread. Finalizing resources that have an affinity to a particular thread is dangerous, you can run into deadlocks if you are not careful, and so on.

  • finalization can "resurrect" a dead object by assigning a reference to it to a variable that is in a live object. Do not do that. It is incredibly confusing.

  • finalizers can run on objects that were partially constructed when a thread abort exception happened. You cannot assume that any invariant that is true of a fully-constructed object is true of an object being finalized.

Writing a finalizer correctly is extremely difficult for all these reasons. Avoid, avoid, avoid.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...