Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.
like image 306
user579674 Avatar asked May 20 '11 00:05

user579674


People also ask

Which function is used to free memory in C?

The C library function void free(void *ptr) deallocates the memory previously allocated by a call to calloc, malloc, or realloc.

How does C deallocate memory?

In C, the library function malloc is used to allocate a block of memory on the heap. The program accesses this block of memory via a pointer that malloc returns. When the memory is no longer needed, the pointer is passed to free which deallocates the memory so that it can be used for other purposes.

How do I free up memory on malloc?

When you no longer need a block that you got with malloc , use the function free to make the block available to be allocated again. The prototype for this function is in stdlib. h .


1 Answers

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?

Yes.

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

If you are asking if the behavior is the same then yes.

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

The memory used by those objects is most certainly collected after the references are deemed to be unused.

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

No, since no object was created then there is no object to collect (dispose is not the right word).

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

If the object's class implements IDisposable then you certainly want to greedily call Dispose as soon as possible. The using keyword makes this easier because it calls Dispose automatically in an exception-safe way.

Other than that there really is nothing else you need to do except to stop using the object. If the reference is a local variable then when it goes out of scope it will be eligible for collection.1 If it is a class level variable then you may need to assign null to it to make it eligible before the containing class is eligible.


1This is technically incorrect (or at least a little misleading). An object can be eligible for collection long before it goes out of scope. The CLR is optimized to collect memory when it detects that a reference is no longer used. In extreme cases the CLR can collect an object even while one of its methods is still executing!

Update:

Here is an example that demonstrates that the GC will collect objects even though they may still be in-scope. You have to compile a Release build and run this outside of the debugger.

static void Main(string[] args) {     Console.WriteLine("Before allocation");     var bo = new BigObject();     Console.WriteLine("After allocation");     bo.SomeMethod();     Console.ReadLine();     // The object is technically in-scope here which means it must still be rooted. }  private class BigObject {     private byte[] LotsOfMemory = new byte[Int32.MaxValue / 4];      public BigObject()     {         Console.WriteLine("BigObject()");     }      ~BigObject()     {         Console.WriteLine("~BigObject()");     }      public void SomeMethod()     {         Console.WriteLine("Begin SomeMethod");         GC.Collect();         GC.WaitForPendingFinalizers();         Console.WriteLine("End SomeMethod");     } } 

On my machine the finalizer is run while SomeMethod is still executing!

like image 136
Brian Gideon Avatar answered Oct 13 '22 07:10

Brian Gideon