How do I know an object has no reference to it and at that point it should be deleted by the .NET garbage collector?
I'm doing a number of cloning of an object. The reason why I'm cloning it because it is a same object but it has different values later on. When I unreference the object from a property of some class, I don't know where that certain cloned object is being referenced anywhere in the program. My idea is to definitely know that a certain unreferenced object should not be referenced anywhere. If they are referenced somewhere else, I need to unreference it (fix it).
My idea is to unreference a certain clone of an object everywhere in the system to garbage collect and free up space.
Is there anyway I check this object .NET? Is there any libraries or something like that. I'm feeling the object I think I deleted is still being referenced somewhere in my program while running, because this program is huge. Because it is referenced somewhere else, it is not being garbage collected.
Thanks for your help.
You can use the WeakReference class to hold a reference to your object, and check its IsAlive property to know whether the object still exists or has been gargabe collected (finalized and deallocated). The principal advantage of WeakReference for your case is this reference doesn't prevent the GC to dispose the object target.
You can explicitly invoke the garbage collector before the check to lower the probablity there's no other reference to that object and the GC just didn't notice yet. However, you can't reliably tell whether there is / is not a certain amount of reference to your object 'in the wild'.
Related
Quote from ( Safe in C# not in C++, simple return of pointer / reference, answer 3) by Eric lippert.
Also, note that it is not any reference to the Person object that keeps it alive. The reference has to be rooted. You could have two Person objects that reference each other but are otherwise unreachable; the fact that each has a reference does not keep them alive; one of the references has to be rooted.
I dont understand, can someone explain what a rooted reference is?
It means a GC root.
Have a read through this article, maybe it will help with your understanding:
GC roots are not objects in themselves but are instead references to objects. Any object referenced by a GC root will automatically survive the next garbage collection. There are four main kinds of root in .NET:
A local variable in a method that is currently running is considered to be a GC root. The objects referenced by these variables can always be accessed immediately by the method they are declared in, and so they must be kept around. The lifetime of these roots can depend on the way the program was built. In debug builds, a local variable lasts for as long as the method is on the stack. In release builds, the JIT is able to look at the program structure to work out the last point within the execution that a variable can be used by the method and will discard it when it is no longer required. This strategy isn’t always used and can be turned off, for example, by running the program in a debugger.
Static variables are also always considered GC roots. The objects they reference can be accessed at any time by the class that declared them (or the rest of the program if they are public), so .NET will always keep them around. Variables declared as ‘thread static’ will only last for as long as that thread is running.
If a managed object is passed to an unmanaged COM+ library through interop, then it will also become a GC root with a reference count. This is because COM+ doesn’t do garbage collection: It uses, instead, a reference counting system; once the COM+ library finishes with the object by setting the reference count to 0 it ceases to be a GC root and can be collected again.
If an object has a finalizer, it is not immediately removed when the garbage collector decides it is no longer ‘live’. Instead, it becomes a special kind of root until .NET has called the finalizer method. This means that these objects usually require more than one garbage collection to be removed from memory, as they will survive the first time they are found to be unused.
(emphasis mine)
There're all kinds of root objects, like CLR internal objects, metadata objects, etc. This post may help:
Variables and GC Roots
A variable of a Value Type is direct representation of the address of the Value Type instance on stack
A reference variable to a Value Type instance is called Managed Pointer and is a pointer to the starting address of the Value Type instance on stack
A variable of a Reference Type (UDT, Array, String, Delegate and Interface type variables) is a pointer to the Reference Type instance created on GC heap
CPU registers can contain Managed Pointers or Object References
AppDomain wide Handle tables contain GC handles that are pointers to the pinned Reference Type instances in memory. These Handle tables also contain Managed Pointers (or Object References?) to the static Value Type instances and Object References to the static Reference Type instances
Thread Local Storage (TLS) can contain Object References
FReachable Queue contains Object References of the Reference Types that are NOT referenced by any of the above variable types and for which finalize method call is pending
CLR's Garbage Collector uses the above variables, also called GC roots, to track down the Object References during garbage collection phase. Any Reference Type instance located in GC heap, for which there is no Object Reference in any of the above variable types (except for the FReachable Queue), is considered a candidate for garbage collection and is removed from GC heap. If the Reference Type instance being removed implements the Finalize method, then the Object Reference is put on FReachable Queue for calling the Finalize method by a separate Finalizer thread. Once the Finalizer thread completes Finalize method call on an Object Reference, the corresponding Reference Type instance is removed from the GC heap.
I would like to know if it is possible to execute some C# code when an object is getting destroyed?
I tried to use IDiposable, but my Dispose method is not getting called.
Thanks.
You might be able to do this through Garbage Collection Notification, which allow you to sense and respond when a full garbage collection is approaching and when the full garbage collection has completed.
Garbage Collection Notifications
If an object creates an instance of a type with a finalizer, keeps a reference to that instance, and does not expose that reference to anyone, then when the object holding the only reference becomes eligible for collection, the finalizer of that latter object will be enqueued to run at the next opportunity. Note that the garbage-collector does not run finalizers; it merely adds finalizable objects to a list of things whose finalizers should run as soon as practical. No objects which is on that list, nor any other object to which it holds a direct or indirect strong reference, will be eligible for collection until it ceases to be on that list. If your finalizable object does not hold a reference to the object that holds the reference to it, and if that other object doesn't have a finalizer of its own, that object will be cease to exist once no references exist to it; by the time the finalizer of the latter object runs, the former object won't exist anymore.
I know the knowledge below:
A weak reference permits the garbage collector to collect the object
while still allowing the application to access the object.
So if the object has been reclaimed, you have to create it again when necessary.
Then, what's the difference between short weak reference and long weak reference? I think of it as below:(according to the msdn)
short weak reference: if GC reclaim the object, the object is really
released.
long weak reference: if GC reclaim the object, the object is still
existed (as it is cached).
So can someone tell me more detail?
Short
The target of a short weak reference becomes null when the object is
reclaimed by garbage collection. The weak reference is itself a
managed object, and is subject to garbage collection just like any
other managed object. A short weak reference is the default
constructor for WeakReference.
Long
A long weak reference is retained after the object's Finalize method
has been called. This allows the object to be recreated, but the state
of the object remains unpredictable. To use a long reference, specify
true in the WeakReference constructor.
If the object's type does not have a Finalize method, the short weak
reference functionality applies and the weak reference is valid only
until the target is collected, which can occur anytime after the
finalizer is run.
To establish a strong reference and use the object again, cast the
Target property of a WeakReference to the type of the object. If
the Target property returns null, the object was collected; otherwise,
you can continue to use the object because the application has
regained a strong reference to it.
Guidelines for Using Weak References
Use long weak references only when necessary as the state of the
object is unpredictable after finalization. Avoid using weak
references to small objects because the pointer itself may be as large
or larger.
Avoid using weak references as an automatic solution to memory
management problems. Instead, develop an effective caching policy for
handling your application's objects.
Reference
I got this idea while thinking of ways to recycling objects. I am doing this as an experiment to see how memory pooling works and I realize that in 99% of scenario this is very unnecessary .
However, I have a question. Is there a way to force the GC to keep the object? In other words, can I tell the GC not to destroy an object and say instead have new reference created in a list that holds available to use objects? The issue, though I have not tested this, is that if I add something like this to a list:
~myObject()
{
((List<myObject>)HttpContext.Current.Items[typeof(T).ToString()]).add(this);//Lets assume this is ASP
}
it will add a pointer to this object into the list, but if the object is destroyed I will get a null pointer exception because the object is no longer there. However, maybe I could tell the GC not to collect this item and thus keeping the object?
I know this is the type of stuff that most programmers would go "why the hell would you do this?". But on the other hand programming is about trying new and learning new things. Any suggestions, thoughts, implementatons? Any help would be greatly appreciated!
Yes, this is legitimate. It is called 'resurrection'. When you assign the this reference to somewhere that is 'live', then the object is no longer considered garbage.
You will also need to reregister for finalization using GC.ReRegisterForFinalize(this), or the next time the object becomes garbage, it will not be finalized (the destructor will not be called).
You can read more about object resurrection in this MSDN Magazine article.
Yes, this is possible and it even has a name: resurrection.
but if the object is destroyed I will get a null pointer exception because the object is no longer there.
Much worse, you would get an invalid pointer (reference) error. And possibly a blue screen or crashing server. But luckily the CLR won't let that happen. Simply putting a doomed instance in any kind of list makes it reachable again and then it will not be reclaimed.
When you want your object to be recycled multiple times you will have to call GC.ReRegisterForFinalize(x) on it.
Most practical answer though: don't do it. The destructor alone accounts for considerable overhead and there are many ways to get this wrong.
The GC is only going to take care of objects whose reference is gone whether by going out of scope of being explicitly released.
Either way you will want to look at the KeepAlive and SuppressFinalize methods to prevent GC from garbage collecting your objects. Once you are truly done with them you'll need to register them to be picked up by the collector using ReRegisterForFinalize.
If an object has 5 references can that object find out what is referenced to him?
Because I know that Java (and hopefully C#) have a list of that for the GC.
No, there's no "list of references". The GC doesn't need to know everything that references an object - it just needs to know if anything references an object.
As a very crude model of what the GC does, it marks every object in the heap as garbage, then looks at objects which it knows to be non-garbage ("root" objects). For example, it will look at the stack of each thread and for each instance method in the thread, it will usually1 mark the target instance as non-garbage.
Then it will go through each of those roots, and see what objects those ones refer to... and mark them as non-garbage. It will recurse down, finding everything it can. Whatever hasn't been marked as non-garbage can then be collected (or finalized).
As you can see from this algorithm, the GC doesn't need to keep a full list of references for each object - just a bit to say "garbage" or "non-garbage".
Obviously in reality the GC is much more complicated than this, in both Java and .NET, with generational garbage collectors and various strategies to minimise the GC "pause" and use multiple threads for GC. Hopefully this simplified view is enough to explain why even the GC doesn't have a list of references though.
1 Not always, in the case of .NET. An object can be garbage collected while an instance method is still running "in" it, if that method doesn't refer to any fields in the object from the current point onwards.
If you fail to find language support for this, simply have each object that wants to hold a reference to the object in question call a method that tells the object in question that it is being referenced. This object would then add the referring object to a list. Whenever you give up your reference to that object, you call another method that would remove the referrer from the list.