As a managed platform,. net releases memory and pointers and is managed by virtual machines (CLR .. Net makes it clear to me what kind of object is garbage, that is, "the object is no longer reachable". This is a good understanding. During the runtime, all objects are organized into a graph, in graph theory, "accessibility" is discussed as a very important property. Although the GC mechanism does not tell us many things, we do not need to worry too much about those things, for example, when GC is triggered, and which object is recycled by a GC.
We know that there is a special type of object, that is, the object constructed by the type of the Terminator, by default (unless GC is called. suppressFinalize (Object obj) method, which will be seen in standard IDispose mode). GC will call the Object terminator when the Object is recycled. In this way, a problem occurs: if the object becomes "reachable" in the object Terminator, is this object still available?
This is purely an academic question. I don't think any application has such a stupid need: I have determined that something is useless and threw it into the garbage, but when the garbage cleaner wants to transport it and bury it, I still get it back from someone else. However, this academic question is still interesting. At least it can tell us whether an object Terminator can be called multiple times, And before calling the object Terminator, whether the GC has destroyed the object.
The so-called no code and no truth, I use the simplest way to implement a "object becomes reachable in The Terminator", the Code is as follows:
Code
1 class Program
2 {
3 static void Main (string [] args)
4 {
5 new MyClass1 (); // construct a MyClass1 object
6 GC. Collect (); // Manual GC
7 MyClass1.Cache. Multex. WaitOne (); // wait until GC is completed
8 MyClass1.Cache. Clear (); // Clear the object
9 MyClass1.Cache. Multex. WaitOne (); // wait until GC is completed
10 Console. WriteLine (MyClass1.Cache. Item. ToString (); // The private global variable of the object is still not null
11 Console. Read ();
12}
13}
14
15
16
17 public class ItemCache <T> where T: class
18 {
19 private readonly AutoResetEvent m_AutoResetEvent = new AutoResetEvent (false );
20 public AutoResetEvent Multex
21 {
22 get {return m_AutoResetEvent ;}
23}
24 private T item;
25 public T Item
26 {
27 get {return item ;}
28 set
29 {
30 if (value! = Null)
31 {
32 item = value;
33 Console. WriteLine ("Item has been set ");
34 m_AutoResetEvent.Set ();
35}
36}
37}
38 public void Clear ()
39 {
40 if (item! = Null)
41 {
42 GC. ReRegisterForFinalize (item );
43 item = null;
44 Console. WriteLine ("Item has been cleared ");
45 GC. Collect ();
46}
47}
48}
49
50 public class MyClass1
51 {
52 public static readonly ItemCache <MyClass1> Cache = new ItemCache <MyClass1> ();
53 public MyClass1 ()
54 {
55 o = new object ();
56}
57
58 ~ MyClass1 ()
59 {
60 Console. WriteLine ("I am over ");
61 Cache. Item = this;
62}
63
64 private object o = null;
65
66 public override string ToString ()
67 {
68 return o! = Null? "I still can do every work! ":" Sorry, I am dead ..";
69}
70}
71
In the MyClass1 type, there is a static Cache, so that the object's this pointer is cached when the Terminator is called, so that the object can be reached again. The Clear method of the ItemCache class calls GC. the ReRegisterForFinalize (Object obj) method re-registers the Object terminator (because the Object Terminator has been called once, so when the object becomes inaccessible again after it is "saved", GC will no longer call the object Terminator). In this way, whenever the object becomes inaccessible, GC will call its terminator, and this method makes the object reachable, thus saving the object and making it endless.
So, when GC decides to recycle the object and call the object Terminator, is the object damaged? A simple example is to add a global private member to the object and instantiate the private object in the constructor. After testing, it is found that even if the object Terminator has been called, as long as the object is not destroyed in the Terminator, GC will not destroy it (that is, the private member is still not null ). That is to say, there is no difference between the saved object in the Terminator and before it is not dead. It also has all its functions before its lifetime. This is a bold assumption, and I have not strictly proved it.
It is worth mentioning that GC will certainly not call the final end of the object in the main thread of the program or any thread we open. Therefore, this test requires the wait and notify (GC) of the thread. the WaitForFullGCComplete () method may block the current thread until GC collection ends, but this. net Framework 3.5sp1 method I didn't understand what is used and how to use it), I implemented it using AutoResetEvent until GC calls the Terminator and saves the object in the method, we will continue other tasks in the main thread to avoid NullReferenceException.
Description of this program. when the final device is called by the. net GC, the space allocated to the object on the managed stack is still not reclaimed (that is, the memory is released ), so it gave us a chance to save an object in the near-death state, although this is not reasonable. This MyClass1 type is fully implemented in the hosting environment, without applying for any unmanaged resources, and I have not implemented the IDispose interface for it. As mentioned in this Article, this is only an academic study with no practical value.
If the argument is not rigorous enough, I hope you can give me some advice.