[c#] What is the correct way to free memory in C#

I have a timer in C# which executes some code inside it's method. Inside the code I'm using several temporary objects.

  1. If I have something like Foo o = new Foo(); inside the method, does that mean that each time the timer ticks, I'm creating a new object and a new reference to that object?

  2. If I have string foo = null and then I just put something temporal in foo, is it the same as above?

  3. Does the garbage collector ever delete the object and the reference or objects are continually created and stay in memory?

  4. If I just declare Foo o; and not point it to any instance, isn't that disposed when the method ends?

  5. If I want to ensure that everything is deleted, what is the best way of doing it:

    • with the using statement inside the method
    • by calling dispose method at the end
    • by putting Foo o; outside the timer's method and just make the assignment o = new Foo() inside, so then the pointer to the object is deleted after the method ends, the garbage collector will delete the object.

This question is related to c# memory memory-leaks

The answer is


The garbage collector will come around and clean up anything that no longer has references to it. Unless you have unmanaged resources inside Foo, calling Dispose or using a using statement on it won't really help you much.

I'm fairly sure this applies, since it was still in C#. But, I took a game design course using XNA and we spent some time talking about the garbage collector for C#. Garbage collecting is expensive, since you have to check if you have any references to the object you want to collect. So, the GC tries to put this off as long as possible. So, as long as you weren't running out of physical memory when your program went to 700MB, it might just be the GC being lazy and not worrying about it yet.

But, if you just use Foo o outside the loop and create a o = new Foo() each time around, it should all work out fine.


  1. Yes
  2. What do you mean by the same? It will be re-executed every time the method is run.
  3. Yes, the .Net garbage collector uses an algorithm that starts with any global/in-scope variables, traverses them while following any reference it finds recursively, and deletes any object in memory deemed to be unreachable. see here for more detail on Garbage Collection
  4. Yes, the memory from all variables declared in a method is released when the method exits as they are all unreachable. In addition, any variables that are declared but never used will be optimized out by the compiler, so in reality your Foo variable will never ever take up memory.
  5. the using statement simply calls dispose on an IDisposable object when it exits, so this is equivalent to your second bullet point. Both will indicate that you are done with the object and tell the GC that you are ready to let go of it. Overwriting the only reference to the object will have a similar effect.

Let's answer your questions one by one.

  1. Yes, you make a new object whenever this statement is executed, however, it goes "out of scope" when you exit the method and it is eligible for garbage collection.
  2. Well this would be the same as #1, except that you've used a string type. A string type is immutable and you get a new object every time you make an assignment.
  3. Yes the garbage collector collects the out of scope objects, unless you assign the object to a variable with a large scope such as class variable.
  4. Yes.
  5. The using statement only applies to objects that implement the IDisposable interface. If that is the case, by all means using is best for objects within a method's scope. Don't put Foo o at a larger scope unless you have a good reason to do so. It is best to limit the scope of any variable to the smallest scope that makes sense.

Here's a quick overview:

  • Once references are gone, your object will likely be garbage collected.
  • You can only count on statistical collection that keeps your heap size normal provided all references to garbage are really gone. In other words, there is no guarantee a specific object will ever be garbage collected.
    • It follows that your finalizer will also never be guaranteed to be called. Avoid finalizers.
  • Two common sources of leaks:
    • Event handlers and delegates are references. If you subscribe to an event of an object, you are referencing to it. If you have a delegate to an object's method, you are referencing it.
    • Unmanaged resources, by definition, are not automatically collected. This is what the IDisposable pattern is for.
  • Finally, if you want a reference that does not prevent the object from getting collected, look into WeakReference.

One last thing: If you declare Foo foo; without assigning it you don't have to worry - nothing is leaked. If Foo is a reference type, nothing was created. If Foo is a value type, it is allocated on the stack and thus will automatically be cleaned up.


The .NET garbage collector takes care of all this for you.

It is able to determine when objects are no longer referenced and will (eventually) free the memory that had been allocated to them.


Objects are eligable for garbage collection once they go out of scope become unreachable (thanks ben!). The memory won't be freed unless the garbage collector believes you are running out of memory.

For managed resources, the garbage collector will know when this is, and you don't need to do anything.

For unmanaged resources (such as connections to databases or opened files) the garbage collector has no way of knowing how much memory they are consuming, and that is why you need to free them manually (using dispose, or much better still the using block)

If objects are not being freed, either you have plenty of memory left and there is no need, or you are maintaining a reference to them in your application, and therefore the garbage collector will not free them (in case you actually use this reference you maintained)


As Brian points out the GC can collect anything that is unreachable including objects that are still in scope and even while instance methods of those objects are still executing. consider the following code:

class foo
{
    static int liveFooInstances;

    public foo()
    {
        Interlocked.Increment(ref foo.liveFooInstances);
    }

    public void TestMethod()
    {
        Console.WriteLine("entering method");
        while (Interlocked.CompareExchange(ref foo.liveFooInstances, 1, 1) == 1)
        {
            Console.WriteLine("running GC.Collect");
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
        Console.WriteLine("exiting method");
    }

    ~foo()
    {
        Console.WriteLine("in ~foo");
        Interlocked.Decrement(ref foo.liveFooInstances);
    }

}

class Program
{

    static void Main(string[] args)
    {
        foo aFoo = new foo();
        aFoo.TestMethod();
        //Console.WriteLine(aFoo.ToString()); // if this line is uncommented TestMethod will never return
    }
}

if run with a debug build, with the debugger attached, or with the specified line uncommented TestMethod will never return. But running without a debugger attached TestMethod will return.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to memory

How does the "view" method work in PyTorch? How do I release memory used by a pandas dataframe? How to solve the memory error in Python Docker error : no space left on device Default Xmxsize in Java 8 (max heap size) How to set Apache Spark Executor memory What is the best way to add a value to an array in state How do I read a large csv file with pandas? How to clear variables in ipython? Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine

Examples related to memory-leaks

AngularJS - Does $destroy remove event listeners? Implementing IDisposable correctly Best way to increase heap size in catalina.bat file If a DOM Element is removed, are its listeners also removed from memory? Resource leak: 'in' is never closed android activity has leaked window com.android.internal.policy.impl.phonewindow$decorview Issue This Handler class should be static or leaks might occur: IncomingHandler possible EventEmitter memory leak detected performSelector may cause a leak because its selector is unknown How can I create a memory leak in Java?