There is a piece of my code which is called repeatedly (2000+ each second). To avoid garbage generation and to reduce performance overhead, I moved all local variables to class level, but I'm not sure if this approach is effective...
My question is...
Variables aren't garbage collected. Objects are garbage collected... and they can be garbage collected any time after the runtime can detect that they're no longer referenced by any live code. This can include objects referred to by local variables:
public void Foo()
{
object x = new object();
// The object can't be collected here...
Console.WriteLine(x);
// But it *can* be collected here
Console.WriteLine("This line doesn't depend on x");
}
It's very rarely a good idea to change a "natural" design for the sake of garbage collection... something which is the state of a method isn't usually naturally part of the state of an object, so turning a local variable into an instance variable is usually a bad idea.
That said, we don't know what those local variables represent, or anything about them - we'll need more context to comment on your specific case.
Consider this very simple example (where SomeObject
is a class, not a struct):
class C
{
void MethodCalledMillionsOfTimes()
{
var so = new SomeObject();
// some use of so
}
}
Each time the method is called, one new object is created on the heap. It needs to be garbage collected some time after the use of it has ended. That is one object to collect per call of the method.
Then suppose it is changed into:
class C
{
SomeObject soField;
void MethodCalledMillionsOfTimes()
{
soField = new SomeObject();
// some use of soField
}
}
This changes nothing! You still create one new instance for each method call. The garbage collector has to do the same amount of work.
But what if you did:
class C
{
SomeObject soField = new SomeObject();
void MethodCalledMillionsOfTimes()
{
// some use of soField
}
}
This time the same object is re-used each time the method is called again on the same instance. So fewer objects need to be garbage collected (assuming the method is actually called many times on the same C
object). Note that this can only work if the SomeObject
instance can be used many times, and does not have its state "ruined" by each use.
If many threads call the method at once, be sure the object soField
can handle that.
If you go further and say:
class C
{
static SomeObject soStaticField = new SomeObject();
void MethodCalledMillionsOfTimes()
{
// some use of soStaticField
}
}
then there's only one object shared between all instances of C
. No SomeObject
will have to be collected by the GC.
However, this GC activity is very often not important for your performance. So please measure if it is important or not in your case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With