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.
Related
I'm sure this has been asked before and I just don't know the right terms to search for. In a C# program I am working on I have an List that keeps track of Objects. Those objects can also be displayed on the screen via references by other objects.
Sometimes after an object is removed from the list it is still temporarily available to those other objects (as it should be)... After those objects are done however I want to make sure the object is 100% gone and not staying in memory still being referenced by a forgotten object... How can I do this?
To be clear, this doesn't need to happen as part of the shipped program, only for debugging.
You normally can't. The GC is meant to take care of memory management behind the scenes, and does it's job very specifically and by means best not trifled with. In particular, other parts of your code may keep a reference to the item you want removed, which SHOULD prevent its collection. such is the nature of memory managed languages such as C#.
That being said, however, there are a few ways to check for when an object is disposed. The easiest to to create a simple destructor and breakpoint it, allowing you to "see" whenever an object is collected.
~MyClass()
{ // Breakpoint here
}
The other way is to make a static list of WeakReferences to your objects, which each object subscribes to when it's created. Make sure to keep that other list, however, as a weak reference is specifically designed to allow garbage collection, allowing you to track an object to its destruction. The other list is necessary to keep the objects alive. Also note that in .NET 4.5, there is a generic version of WeakReference. EDIT: This is definitely the solution I recommend after seeing the updates to your question. You can also quickly query which objects are still being refernced via Linq
var leftoverObjects = WeakCache
.Select(wr => wr.Target)
.OfType<MyObject>() // Only if you're not using that Generic Weak Reference
.Except(ObjectList); // filters away objects in the List
Be warned the above query creates a result which has strong references, so once run, it'll keep those objects in memory as long as the result is referenced.
If you have some sort of unmanaged memory backing your object, that's exactly what the IDisposable interface is designed for.
UPDATE: finally, if you MUST do so, you can Force the GC to Collect. This is often heavily advised against, as you start to warp the Generations that help optimize the GC in the first place.
I guess you need this for testing purpose. In such case I would recommend to use memory profiler such as ANTS Memory Profiler or JetBrains dotTrace. You can find more complete list of profilers here
There is no easy way to look for an object reference "backwards", basically you would need to use reflection to loop through all objects and structs that exist in the application and check all references. You just have to make sure that all code that uses the reference really removes it when they are done.
One way to check if there seems to be any live references (but not where they are) is to keep a list of weak references to the objects that you don't use any more. The weak references will not keep the objects from being collected, but you can use them to check if the objects have been collected or not.
As there is no guarantee that an object should be collected within any certain time, you can never know for sure if it's an actual reference that keeps an object alive, but the longer the objects survive, the more likely it is that you have a reference to it somewhere.
I am reading CLR Via C# and on the garbage collection topic it is mentioned that the objects that have a finalize method are added to another list.
If no root exists to this particular object then how can the finalize of that object be called?
Have I understood something wrong. Please explain this particular gap/link/detail if possible?
.NET is a memory managed platform. It knows of each and every one of your objects, even if there are no roots in the memory (heap, stack, etc.) of the application.
It is documented in many places, this is one of my favorites: http://msdn.microsoft.com/en-us/magazine/cc163791.aspx
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.
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'.
This is a .net CLR related question.
I have 3 objects object A,B,C
A refres B and B refers c
What happens to these objects in the heap if i kill the Object "A" explicitly.Which will be garbage collected?(Object A or B or c or all?)
Can some one explain the garbage collection process in this scenario in detail.
Thanks in advance
SNA
First - you can't "kill the Object "A" explicitly"; you can clear the reference to it, but that just sets a local variable to null, and has nothing to do with the actual object on the managed heap. You can Dispose() it, but that is nothing to do with GC.
It all depends; can anything else see B / C? If not, they are eligible for collection. But GC is non-deterministic; it only happens when it chooses. At some indeterminate time, GC will kick in, detect that these objects are unreachable, and remove them. In the process, it will check for any that have finalizers (that are still outstanding), and execute the finalizers (in a 2-step process).
One thing people often forget about in terms of reachability is events; if B/C subscribe to events on a long-lived object, then B/C are reachable (by the event publisher).
To clarify; GC works by building a tree from the root objects (threads, etc). It walks every reference, flagging all the objects that can be reached. Anything that isn't flagged at the end is eligible for collection. This avoids the COM/COM+ issue of getting memory leaks due to disconnected islands of data, where X => Y and Y => X (so both X and Y have positive ref-counts, so neither gets cleared).
The first misunderstanding might be that you cannot kill a managed object explicitly.
You can free unmanaged memory that you allocated yourself, but that isn't managed and by that not subject to garbage collection anyway.
When you set the reference to A to null or it runs out of scope, then there wouldn't be any references to B & C, and the next GC collection will take care of it.
In .NET there is no way to actually kill/remove an object. All you can do explicitly is to disose an object. This nothing more that a simple call to Dispose() on your object. This will allow you to cleanup your object before it might get collected by the garbage collector at a later time (that you can not really infulence). See IDisposable on more details. The 2nd option to get a chance to cleanup your object before it gets collected by the GC is to implement a finalizer. Unlike the Dispose() this will be called by the GC automatically. Again, both are just way to cleanup any resources before an object might stop to exist.
So to answer your question if your object A gets "killed" wich only happens when it is not referenced by any other object anymore B and C will get "killed" to IF they are only referenced through A. Usually you do not have any influence on when this actually happens. All you can do is to implement the finalizer to get notified when it happens.
The GC is a background service that runs on a separate thread that follows a complex logic when to actually delete objects.
If you want to get a basic understanding on how the GC works I would suggest the following two articles. Allthough a bit old they still fully apply.