Is there a way to invoke the garbage collector on a specific object within managed memory from an application?
e.g. (in pseudo-code)
Read myString from file;
perform arbitrary operation on myString;
invoke garbage-collector to remove myString
Is there a way to invoke the garbage collector on a specific object within managed memory from an application?
e.g. (in pseudo-code)
Read myString from file;
perform arbitrary operation on myString;
invoke garbage-collector to remove myString
GC.Collect() it'll tell it to run a collection. But, it won't collect specific objects. The GC is non-deterministic in relation to which objects are collected or not and when.
There is a Collect method on the Garbage collector, but it should be avoided 99.999% of the time for performance reasons. It's hard to predict the right time to clean up those objects.
http://msdn.microsoft.com/en-us/library/system.gc.collect.aspx
Currently* there is no managed API to invoke the GC on a specific object.
at Dec 17, 2009: .NET 3.5 SP1 and .NET 4.0 Beta 2 do not have it.
To the best of my knowledge it's not possible to be this specific with collection with C#.
It's often cited as one of the cons of C# compared to C/C++.
That said, it would be interesting to know why you want to do this, it does sounds a little like premature performance work. Lots of great advice against this in interesting book I'm reading now, "Coders at Work".
You shouldn't need it, if it is a string.
It will be collected, when you make sure that there are no references hanging on to it.
To force garbage collection, you could create a class that implements IDisposable
interface, provide necessary implementation, use that class in the code & release it by calling Dispose
on it.
e.g.
using (WrapsTheStringAndIsDisposable blah = new WrapsTheStringAndIsDisposable())
{
.....
}
I would go on to say, don't worry about it.
To add to the other wonderful answers...
Be aware that it is very unlikely you need to actually call GC.Collect() yourself. The garbage collector is very smart and knows when to do its business. See Scott Holden's blog post about GC for more info.
No, and it wouldn't have an effect in any case:
Think about it this way. Say you had a custom class, MyBigMemoryClass
, that you wanted to collect an instance of - you'd have to have some way to pass a reference of that to the garbage collector. In a theoretical world, it would be something like:
// Not valid code!
MyBigMemoryClass instance = GetMyInstance();
GC.CollectObject(instance);
However, at this point, you still have a reference to the instance of your class in the instance
variable, so the object is still rooted, and not a candidate for garbage collection. The GC would see that its rooted, and leave it be.
The closest you can do is to unroot your object instance, and then have the garbage collector try to collect everything:
MyBigMemoryClass instance = GetMyInstance();
// Do something with instance
instance = null; // Unroot this, so there are (hopefully) no references to it left
GC.Collect(); // Collect everything
That being said, this is typically a very bad idea. It's much better to never call the garbage collector, and allow it to manage the memory for you. There are very few exceptions to this, mostly when working with native code, and those exceptions are typically handled better by using GC.AddMemoryPressure and GC.RemoveMemoryPressure.
Lately I had a handle overflow problem at work. In Windows, one process can only have 10 000 handles max. Security Issues.
Any way here is what worked out: - Call dispose on controls that are closed or hidden - Call GC.Collect - If a call occurs on a control that was disposed, but its needed again, recreate it.
Basic usage is with the tab controls. We have many of them. Each tab control holds around 10-20 tabs a user can click on. But there is only 1 tab selected at the moment. If the handle count is near 10 000, we clear all objects that are on hidden tabs.
On a tab show we recreate them if they are needed.