In C#, the garbage collector will manage all object and release the memory of any objects which no longer have any references.
Using your example:
RandomObject x;
// A RandomObject reference is defined.
x = new RandomObject(argX, argY);
// Memory is allocated, a new RandomObject object is created in that memory location,
// and "x" references that new object.
x = new RandomObject(argZ, argV);
// Memory is allocated, a new RandomObject object is created in that memory location,
// and "x" references that new object. The first RandomObject object no longer has
// any references to it and will eventually be cleaned up by the garbage collector.
Unmanaged Resources
Even though all objects in C# are managed, there are "unmanaged resources" such as open files or open connections. When an object with an unmanaged resource goes out of scope it will be garbage collected, but the garbage collector will not release those unmanaged resources. Those objects usually implement IDisposable
which allows you to dispose of the resource before it is cleaned up.
For example, there is an unmanaged resource in the StreamWriter
class, which opens a file and writes to it.
Here's an example of failing to release an unmanaged resource:
// This will write "hello1" to a file called "test.txt".
System.IO.StreamWriter sw1 = new System.IO.StreamWriter("test.txt");
sw1.WriteLine("hello1");
// This will throw a System.IO.IOException because "test.txt" is still locked by
// the first StreamWriter.
System.IO.StreamWriter sw2 = new System.IO.StreamWriter("test.txt");
sw2.WriteLine("hello2");
To correctly release the file you must do the following:
// This will write "hello1" to a file called "test.txt" and then release "test.txt".
System.IO.StreamWriter sw1 = new System.IO.StreamWriter("test.txt");
sw1.WriteLine("hello1");
sw1.Dispose();
// This will write "hello2" to a file called "test.txt" and then release "test.txt".
System.IO.StreamWriter sw2 = new System.IO.StreamWriter("test.txt");
sw2.WriteLine("hello2");
sw2.Dispose();
Luckily, objects that implement IDisposable
can be created in a using
statement, then when it goes out of scope Dispose()
will automatically be called on it. This is better than manually calling Dispose (like in the previous example) because if there were any unexpected exit points in the using block you can rest assured that your resource has been released.
using (System.IO.StreamWriter sw1 = new System.IO.StreamWriter("test.txt"))
{
sw1.WriteLine("hello1");
}
using (System.IO.StreamWriter sw2 = new System.IO.StreamWriter("test.txt"))
{
sw2.WriteLine("hello2");
}