How are objects generated using reflection garbage collected? - c#

One of my friend told me that dynamic method is the only way if you want to at run time construct code that can be garbage collected.
One question in my mind that how garbage collector garbage the object which generated using reflection?

An object constructed using reflection will be garbage collected like any other type of object, for example when it leaves the scope of a method if it's a method variable.

Garbage collection will collect any .NET objects. It doesn't differ wether they are created using reflection or not.

how should an object created by reflection be different than one created normally?
you have an instance variable of this object... the runtime exactly knows what type of object it is, and also does the GC.
only the way the object is created is different. the object should be exactly the same as one created with new MyObject()

There is more complexity than this.
For example, search for Tess (good MS employee) blog about xml serializer leaking memory.
There are ways to fix this in code pattern. Anyway, this xml serializer memory leak problem won't be fixed by GC. In fact, these types of dynamically generated dll only get deleted when the parent app is unloaded (IIS worker process that hosts web service that use xml serializer).
Bottom line: even for .Net project, don't rely on GC for all cases. There are leaks that need work-around code/code pattern fix.
This bug is still in 3.5 I think.
More link:
http://plainoldstan.blogspot.com/2011/04/wcf-memory-leak-with.html
read the Tess link an other link inside this:
Are there still known memory leaks with XMLSerialization in .Net 3.5?

Any piece of code that runs under the control of CLR is managed code and CLR governs and decides for garbage collection.
there are ways in which you can coltrol the Garbage collection but unless it is really required let CLR decide.

Related

Is it possible to perform manually deleting of object in .NET?

In the unmanaged languages like C++ I can delete object using delete operator. But .NET platform is managed, so only the garbage collector can delete object from memory. We can only remove all references to the object and Garbage Collector will collect it sometime. But I want to perform instant delete of object.
Is there a way delete object using C++ library? The main idea:
Create C++ library
Define method DeleteUnsafe(void* pointer) that uses mscoree.dll to delete object
Refer to the C++ library from .NET using DllImport attribute
Is it possible to perform second step? Or use some another way to achieve my goal? What the start point?
Is it possible to perform without corrupting CLR? For example, GC will try collect already deleted object. How we can remove the object from GC queue?
Not too sure about the why you want to do this, but I'll assume you have a reason.
What comes to mind would be forcing garbage collection, but here's a quote from MS:
"It is possible to force garbage collection by calling Collect, but
most of the time, this should be avoided because it may create
performance issues. "
(you can have a look here for more: https://stackoverflow.com/a/233647/1698987.
Other than that, if you really need that fine control, maybe c# ain't the answer?
hmm ... have a look at this msdn page. Seems that calling GC.Collect method assuming that you know what you're doing isn't that bad after all... :)

Determine if Object has been destroyed (i.e no longer found anywhere) in C#

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.

How does CLR call finalize on an object if it knows that no root to that object exists?

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

C# - Preparing An Object For GC Before Calling GC.Collect

Scenario
Lets say that I've decided I really need to call GC.Collect();
What do I need to do to ensure that an object is prepared to be garbage collected appropriately before I actually call this method?
Would assigning null to all properties of the object be enough? Or just assigning null to the object itself?
If you really need to know why.....
I have a distributed application in WCF that sends a DataContract over the wire every few seconds, containing 8 Dictionaries as DataMembers.
This is a lot of data and when it comes into the Client-side interface, a whole new DataContract object is created and the memory usage of the application is growing so big that I'm getting OutOfMemory Exceptions.
Thanks
EDIT
Thanks for all the comments and answers, it seems that everyone shares the same opinion.
What I cannot understand is how I can possibly dispose correctly because the connection is open constantly.
Once I've copied the data over from the incoming object, I don't need the object anymore, so would simply implementing IDisposable on that DataContract object be enough?
My original problem is here - Distributed OutOfMemory Exceptions
As long as nothing else can see the object it is already eligible for collection; nothing more is required. The key point here is to ensure that nothing else is watching it (or at least, nothing with a longer lifetime):
is it in a field somewhere?
is it in a variable in a method that is incomplete? (an infinite loop or iterator block, perhaps)
is it in a collection somewhere?
has it subscribed to some event?
it is captured in a closure (lambda / anon-method) that is still alive?
I genuinely doubt that GC.Collect() is the answer here; if it was eligible it would have already been collected. If it isn't elgible, calling GC.Collect() certainly won't help and quite possibly will make things worse (by tying up CPU when nothing useful can be collected).
You don't generally need to do anything.
If the object is no longer referenced then it's a candidate for collection. (And, conversely, if the object is still referenced then it's not a candidate for collection, however you "prepare" it.)
You need to clean up any unmanaged resources like database connections etc.
Typically by implementing IDisposable and call Dispose.
If you have a finalizer you should call GC.SuppressFinilize.
The rest is cleaned up by the garbage collector.
Edit:
And, oh, naturally you need to release all references to your object.
But, and here is this big but. Unless you have a very very special case you don't need to call GC.Collect. You probably forgets to release some resources or references, and GC.Collect won't help you with that. Make sure you call Dispose on everything Disposable (preferably with the using-pattern).
You should probably pick up a memory profiler like Ants memory profiler and look where all your memory has gone.
If you have no more direct reference to an object, and you're running out of memory, GC should do this automatically. Do make sure you call .Dispose() on your datacontext.
Calling GC.Collect will hardly ever prevent you from getting OutOfMemory exceptions, because .NET will call GC.Collect itself when it is unable to create a new object due to OOM. There is only one scenario where I can think of and that is when you have unreferenced objects that are registered in the finalizable queue. When these objects reference many other objects it can cause a OOM. The solution to this problem is actually not to call GC.Collect but to ensure that those objects are disposed correctly (and implement the dispose pattern correctly when you created those objects).
Using GC.Collect in general
Since you are trying to get rid of a very large collection, it's totally valid to use GC.Collect(). From the Microsoft docs:
... since your application knows more about its behavior than the runtime does, you could help matters by explicitly forcing some collections. For example, it might make sense for your application to force a full collection of all generations after the user saves his data file.
"Preparing" your objects
From the excellent Performance Considerations for Run-Time Technologies in the .NET Framework (from MSDN):
If you keep a pointer to a resource around, the GC has no way of knowing if you intend to use it in the future. What this means is that all of the rules you've used in native code for explicitly freeing objects still apply, but most of the time the GC will handle everything for you.
So, to ensure it's ready for GC, Make sure that you have no references to the objects you wish to collect (e.g. in collections, events, etc...). Setting the variable to null will mean it's ready for collection before the variable goes out of scope.
Also any object which implements IDisposable should have it's Dispose() method called to clean up unmanaged resources.
Before you use GC.Collect
Since it looks like your application is a server, using the Server GC may resolve your issue. It will likely run more often and be more performant in a multi-processor scenario.
The server GC is designed for maximum throughput, and scales with very high performance.
See the Choosing Which Garbage Collector to Use within Performance Considerations for Run-Time Technologies in the .NET Framework (from MSDN):

How do you get rid of an object in c#

In the following c# code, how do I get rid of the objects when it's no longer useful? Does it get taken care of automatically, or do I need to do something?
public void Test()
{
object MyObject = new object();
... code ...
}
Automatically. When MyObject goes out of scope (at the end of Test), it's flagged for garbage collection. At some point in the future, the .NET runtime will clean up the memory for you
Edit:
(I should point out for the sake of completeness that if you pass MyObject somewhere, it gets passed by reference, and will not be garbage collected - it's only when no more references to the object are floating around that the GC is free to collect it)
Edit: in a release build, MyObject will usually be collected as soon as it's unused (see my answer for more details --dp)
The short answer is: unless it has unmanaged resources (file handles etc) you don't need to worry.
The long answer is a bit more involved.
When .NET decides it wants to free up some memory, it runs the garbage collector. This looks for all the objects which are still in use, and marks them as such. Any local variable (in any stack frame of any thread) which may still be read counts as a root as do static variables. (In fact I believe that static variables are referenced via live Type objects, which are referenced via live AppDomain objects, but for the most part you can regard static variables as roots.)
The garbage collector looks at each object referred to by a root, and then finds more "live" references based on the instance variables within those objects. It recurses down, finding and marking more and more objects as "live". Once it's finished this process, it can then look at all the rest of the objects and free them.
That's a very broad conceptual picture - but it gets a lot more detailed when you think of the generational model of garbage collection, finalizers, concurrent collection etc. I strongly recommend that you read Jeff Richter's CLR via C# which goes into this in a lot of detail. He also has a two part article (back from 2000, but still very relevant) if you don't want to buy the book.
Of course all this doesn't mean you don't need to worry about memory usage and object lifetimes in .NET. In particular:
Creating objects pointlessly will cost performance. In particular, the garbage collector is fast but not free. Look for simple ways to reduce your memory usage as you code, but micro-optimising before you know you have a problem is also bad.
It's possible to "leak" memory by making objects reachable for longer than you intended. Two reasonably common causes of this are static variables and event subscriptions. (An event subscription makes the event handler reachable from the event publisher, but not the other way round.)
If you use more memory (in a live, reachable way) than you have available, your app will crash. There's not a lot .NET can do to prevent that!
Objects which use non-memory resources typically implement IDisposable. You should call Dispose on them to release those resources when you're finished with the object. Note that this doesn't free the object itself - only the garbage collector can do that. The using statement in C# is the most convenient way of calling Dispose reliably, even in the face of an exception.
The other answers are correct, unless your object is an instance of a class which implements the IDisposable interface, in which case you ought to (explicitly, or implicitly via a using statement) call the object's Dispose method.
In optimized code, it is possible and likely that MyObject will be collected before the end of the method. By default, the debug configuration in Visual Studio will build with the debug switch on and the optimize switch off which means that MyObject will be kept to the end of the method (so that you can look at the value while debugging). Building with optimize off (debug doesn't matter in this case) allows MyObject to be collected after it's determined to be unused. One way to force it to stay alive to the end of the method is to call GC.KeepAlive(MyObject) at the end of the method.
This will force the garbage collector to get rid of unused objects.
GC.Collect();
GC.WaitForPendingFinalizers();
If you want a specific object to be collected.
object A = new Object();
...
A = null;
GC.collect();
GC.WaitForPendingFinalizers();
It gets taken care of automatically.
Typically garbage collection can be depended on to cleanup, but if your object contains any unmanaged resources (database connections, open files etc) you will need to explicitly close those resources and/or exceute the dispose method on the object (if it implements IDisposable). This can lead to bugs so you need to be careful how you deal with these types of objects. Simply closing a file after using it is not always sufficient since an exception before the close executes will leave the file open. Either use a using block or a try-finally block.
Bottom line: "using" is your friend.

Categories

Resources