I have a piece of code like this:
Class Program
{
static StreamReader sr = null;
static int var=0;
static Program()
{
sr = new StreamReader("input.txt")
}
~Program()
{
sr.Dispose();
}
static void main(string args[])
{
//do something with input here
}
}
This may not be a good practice, but I just want to use this example to ask how the deconstructor and GC works.
My question is: Will ~Program() get called at a non-determined time or it won't be called at all in this case. If the deconstructor won't get called, then how GC collect the unmanaged resources and managed resources.
It probably wouldn't reclaim those resources until the AppDomain or process is unloaded.
If you never instantiate an object, it will never be destroyed. This is exactly why you want, probably something like a Singleton. I believe there is a flavor called "Phoenix Singleton," that will allow a Singleton to be cleaned up and then rebuilt when it is needed again. You could implement it using a WeakReference to the singleton object.
In any case, for a simple program that runs for a bounded period of time, I wouldn't worry about it unless it becomes a problem... the resources will be cleaned up when the process exits.
Your case is quite unclear, as the finalizer would not be called without creating an instance of the class.
However, only calling dispose does nothing towards garbage collection of the object itself, it merely tells the object to release any resource (especially handles etc.). So if you want the GC to collect the instance, you need to set the reference to null, and if there is no other live reference to the instance it will eventually be collected.
Basically each static reference can be seen as root reference, which is included in the GC checks for live references. All instances which cannot be reached through a live reference (directly or indirectly) are candidates for collection. It does not matter if the reference "variable" was static or not.
There is no such thing as a static finalizer (destructor) in C#. Therefore, unless an instance of Program is ever actually created, ~Program() will never be called.
When (if) it is called, it only calls the Dispose() method of the StreamReader; because a reference to the StreamReader is still retained after the finalizer is called, the instance will never be garbage collected until the program exits.
A static reference will root an instance until it is explicitly set to null or its assembly is unloaded. If neither of these happens the instance a static reference points to will remain in use and thus will not be collected. If it isn't eligible for garbage collection its finalizer will not be called either.
Btw GC only handles managed memory. It doesn't handled unmanaged resources. For that you need IDiposable and/or finalizers.
Related
I'm writing a Singleton class for access to a List. When the Singleton is first initialized this List is populated by de-serializing an xml file.
This all works great but I want this List to be updatable and in order to do so I'm currently having to re-serialize each time I add or remove from it.
I would prefer to simply have one call to serialize the list when the object is removed from memory. However I feel that trying to do this in the ~Destructor can potentially cause lost data etc.
What is the best pattern to follow to achieve this behavior?
Thanks
Destructors in C# are very different from C++ destructors. They are not actual destructors that are run on fully correct objects which are no longer required, but a last resort measure to deal with unmanaged resources (MSDN):
You should override Finalize for a class that uses unmanaged resources
such as file handles or database connections that must be released
when the managed object that uses them is discarded during garbage
collection.
So it is a bad idea to use Finalizer (Destructor) to interoperate with managed resources, because:
The finalizers of two objects are not guaranteed to run in any
specific order, even if one object refers to the other. That is, if
Object A has a reference to Object B and both have finalizers, Object
B might have already been finalized when the finalizer of Object A
starts.
Deserialized data list may be correct during such finalization, or it may have been already reclaimed during previous GC runs. Even if it is not so with current garbage collector, no one can guarantee that such problem won't appear in the next .NET version. Accessing managed resources in Finalizer's is practically an undefined behaviour.
Possible solution
Taking into account that your object is singleton, and thus it can be garbage collected only when application exits (or never if it is never requested),
the simplest way to allow such persistent storage to object's data is to attach event handler to the application close(exit) event.
...
public static Singleton Instance
{
get
{
if (_Instance == null)
{
_Instance = new Singleton();
Application.Exit += (sender, args) =>
{
_Instance.SaveChanges();
}
}
return _Instance;
}
}
Or use appropriate Lazy<T> constructor if your Singleton is based on its use.
I always thought that the answer to this was no, but I cannot find any source stating this.
In my class below, can I access (managed) fields/properties of an instance of C in the finalizer, i.e. in ReleaseUnmanaged()? What restrictions, if any, are there? Will GC or finalization ever have set these members to null?
The only thing I can find is that stuff on the finalizer queue can be finalized in any order. So in that case, since the recommendation is that types should allow users to call Dispose() more than once, why does the recommended pattern bother with a disposing boolean? What bad things might happen if my finalizer called Dispose(true) instead of Dispose(false)?
public class C : IDisposable
{
private void ReleaseUnmanaged() { }
private void ReleaseOtherDisposables() { }
protected virtual void Dispose(bool disposing)
{
ReleaseUnmanaged();
if (disposing)
{
ReleaseOtherDisposables();
}
}
~ C()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
In general case - yes, you can. If a class has nonempty finalizer, first time GC would collect instance of this class, it calls finalizer instead (only if you didn't call GC.SuppressFinalize on it earlier). Object instance seen from finalizer looks just like it did last time you touched it. You can even create new (direct or indirect) link from root to your instance and thus resurrect it.
Even if you hold unmanaged pointer to unpinned object and inspect raw memory contents, you shouldn't be able to see partially-deallocated object, because .NET uses copying GC. If an instance is alive during collection, it is either promoted to next generation or moved to completely new memory block along with other instances. If it is not reachable it is either left where it was or the whole heap is released and returned to OS. Keep in mind, however, that finalizers can and will be called on instances of objects that failed to construct (i.e. when was an exception thrown during object construction).
Edit: As for Dispose(true) vs Dispose(false) in well-written classes there shouldn't be much of a difference in the long run. If your finalizer called Dispose(true), it would only remove links from your object to other objects, but since your object is already nonreachable, releasing other instances referenced by your object won't matter their reachability.
For more details on .NET GC implementation details, I recommend C# 5.0 in a Nutshell by Joseph and Ben Albahari.
The GC will never collect any object if there is any way via which any code could ever get a reference to it. If the only references that exist to an object are weak references, the GC will invalidate them so that there's no way any code could ever get a reference to that object, whereupon it will then be able to collect it.
If an object has an active finalizer, then if the GC would collect it (but for the existence of the finalizer), the GC will instead add it to a queue of objects whose finalizers should be run ASAP and, having done so, de-activate it. The reference within the queue will prevent the GC from collecting the object until the finalizer has run; once the finalizer finishes, if no other references exist to the object and it hasn't re-registered its finalizer, it will cease to exist.
The biggest problems with finalizers accessing outside objects are:
A finalizer will be run in a threading context which is unrelated to any threading context where the object was used, but should not perform any operations which cannot be guaranteed to complete quickly. This often creates contradictory requirement that code use locking when accessing other objects, but that code not block while waiting on locks.
If a finalizer has a reference to another object which also has a finalizer, there's no guarantee as to which will run first.
Both of these factors severely limit the ability of objects with finalizers tosafely access outside objects they don't own. Further, because of the way finalization is implemented, it's possible for the system to decide to run a finalizer when no strong references exist, but for external strong references to be created and used before the finalizer runs; the object with the finalizer has no say in whether that happens.
My understanding is that when the GC finds a sub-graph of objects that are no longer accessible (via strong references) from the main graph, it will collect them up and reclaim the memory. My question is concerning the order in which inaccessible objects are deleted. Does this occur as an atomic operation? Are all of the inaccessible objects finalized at once, or does the GC finalize each object one-by-one while the application is still executing? If the objects are finalized one-by-one, is there a particular order that is followed?
If I have an object A that holds a weak reference to object B, then it is clear that A must check if B is still alive before invoking any of B’s instance methods. Now suppose B holds a strong reference to another object C. If B is still alive, am I always guaranteed that C will also still be alive? Is there any possibility that the GC might have marked both B & C for collection, but C is finalized before B?
My guess is that it will always be safe to access C from B (since this is a strong reference). But I would like to confirm this assumption, because if I am wrong I could introduce a very intermittent hard-to-track-down bug.
public class ClassA
{
private readonly WeakReference objBWeakRef;
public ClassA(ClassB objB)
{
objBWeakRef = new WeakReference(objB);
}
public void DoSomething()
{
// The null check is required because objB
// may have been cleaned-up by the GC
var objBStrongRef = (ClassB) objBWeakRef.Target;
if (objBStrongRef != null)
{
objBStrongRef.DoSomething();
}
}
}
public class ClassB
{
private readonly ClassC objCStrongRef;
public ClassB(ClassC objC)
{
objCStrongRef = objC;
}
public void DoSomething()
{
// Do I also need to do some kind of checking here?
// Is it possible that objC has been collected, but
// the GC has not yet gotten around to collecting objB?
objCStrongRef.DoSomething();
}
}
public class ClassC
{
public void DoSomething()
{
// do something here... if object is still alive.
}
}
Yes, if your ClassB has a reference to a ClassC instance via objCStrongRef, then if the ClassB is still alive you don't need to worry about the ClassC evaporating at random. The exception to this is if you write a finalizer, i.e.
~ClassB() { ...}
In there, you should not attempt to talk to objCStrongRef at all; because you can have no clue which object gets finalized first. If ClassC needs something at finalization, it should have a separate ~ClassC() - although in reality finalizer methods are really rare and you shouldn't add them without good reason (unmanaged handles, etc)
Re finalization order: no, there is no particular order followed, because full loops are possible - and it needs to be broken somewhere arbitrarily.
In normal managed methods, you can rely on everything that B refers to with strong references to be alive as long as B is alive. The reference to C from B will be good for the lifetime of B.
The exception is in finalization code. If you implement a finalizer (which should be considered an unusual case, not the norm), then all bets are off within the call chain of the finalizer. Finalizers may not execute for a long time after the GC notices that the objects are no longer referenced by live objects - objects with finalizers tend to hang around a lot longer than "normal" objects, which is another reason not to use finalizers. A finalizer may not execute at all, ever, in extreme panic shutdown corner cases. You can't assume anything about what thread the finalizer will execute on, or what order finalizers will execute in. And you should avoid referring to any reference variables in your object because you don't know if they have already been finalized.
This is all academic though. Your code example doesn't implement a finalizer, so you don't need to worry about the bizzarro finalizer world.
From the "CLR via C#" by Jeffrey Richter:
Furthermore, be aware of the fact that you have no control over when
the Finalize method will execute. Finalize methods run when a garbage
collection occurs, which may happen when your application requests
more memory. Also, the CLR doesn’t make any guarantees as to the order
in which Finalize methods are called, so you should avoid writing a
Finalize method that accesses other objects whose type defines a
Finalize method; those other objects could have been finalized
already. However, it is perfectly OK to access value type instances or
reference type objects that do not define a Finalize method. You also
need to be careful when calling static methods because these methods
can internally access objects that have been finalized, causing the
behavior of the static method to become unpredictable.
If there exists no reference path of any sort which can reach an object, there will be no means to examine the memory space that object used to occupy, unless or until such time as the GC has run and made that memory space usable for reuse and some new object is created that uses it; by the time that occurs, the old object won't exist anymore. Regardless of when the GC runs, an object becomes instantly inaccessible the moment the last reference to it is destroyed or becomes inaccessible.
Objects with active finalizers always have a reference path, since a data structure called the "finalization queue" holds a reference to every such object. Objects in this queue are the last things processed by the GC; if an object is found to be referenced by the queue but by nothing else, a reference will be stored in a structure called the "freachable" queue, which lists objects whose Finalize method should be run at first opportunity. Once a GC cycle completes, this list will be considered a strong rooted reference, but the finalizer thread will start pulling things out of it. Typically, once items get pulled from the list there won't be any reference to them anywhere and they'll disappear.
Weak references add another wrinkle, since objects are considered eligible for collection even if weak references to them exist. The simplest way to regard those as working is to figure that once every object requiring retention has been identified, the system will go through and invalidate every WeakReference whose targets do not require retention. Once every such WeakReference instances has been invalidated, the object will be inaccessible.
The only situation where atomic semantics might matter would be when two or more WeakReference instances target the same object. In that scenario, it might theoretically be possible for one thread to access the Target property of a WeakReference at the exact moment that the GC was invalidating another WeakReference which had the same target. I don't think this situation can actually arise; it could be prevented by having multiple WeakReference instances that share the same target also share their GCHandle. In that case, either the access to the target would happen soon enough to keep the object alive, or else the handle would be invalidated, effectively invalidating all WeakReference instances that hold a reference to it.
I have a timer in C# which executes some code inside it's method. Inside the code I'm using several temporary objects.
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?
If I have string foo = null and then I just put something temporal in foo, is it the same as above?
Does the garbage collector ever delete the object and the reference or objects are continually created and stay in memory?
If I just declare Foo o; and not point it to any instance, isn't that disposed when the method ends?
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.
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!
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)
Let's answer your questions one by one.
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.
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.
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.
Yes.
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.
Yes
What do you mean by the same? It will be re-executed every time the method is run.
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
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.
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.
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.
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.
I ran the following code and found that finalizer is always called. But many articles said that finalizer is non-desterministic.
class Test
{
Test()
{
throw new Exception();
}
~Test()
{
Console.WriteLine("Finalizer is called");
}
static void Main()
{
try
{
new Test();
}
catch { }
}
It is still non-deterministic in your case. Non-deterministic means the amount of time it takes for something to happen cannot be pre-calculated. Note that being unable to correctly determine when something will happen does not necessarily mean random-time but in most cases they are roughly the same.
People who never have to control car brakes, industrial robots or the space shuttle generally should not care weather a piece of code is deterministic or not.
note: I have written code to control industrial robots so I sometimes need to care about my code being executed at the exact moment I want it to be.
The garbage collector calls the finalizer when it collects the object. You can suppress the finalizer call by calling GC.SuppressFinalize(); Documentation
You could place this call inside Dispose() to stop the garbage collector from collecting the class after its resources have been disposed.
In your case, the finalizer is running as part of application shutdown. From the docs:
During shutdown of an application
domain, Finalize is automatically
called on objects that are not exempt
from finalization, even those that are
still accessible.
Non-deterministic refers to when Finalize will be called. But except in exceptional cases (like power being cut off or the process being abruptly killed), the finalizer will eventually be called.
There are cases when it may not be called; and cases where even if it is called, it may not be allowed to complete.
While there are certain occasions when the finalizer will not be called, it will typically be called. The big issue is when it is called, hence it is non-deterministic.
C# is garbage-collected and the garbage collector runs at unspecified intervals. Therefore, if the finalizer needs to do something time-sensitive, it is best to use Dispose instead of a finalizer. For example, you might want to close a database connection immediately instead of leaving it open while waiting for the garbage collector.
That code is so simple that the .NET Runtime can run the finalizer with out problems but in high load applications the Finalizers are only called when garbage collection runs.
There is here an extract of this article
http://msdn.microsoft.com/en-us/magazine/bb985010.aspx
Finalization
The garbage collector offers an additional feature that you may want to take advantage of: finalization. Finalization allows a resource to gracefully clean up after itself when it is being collected. By using finalization, a resource representing a file or network connection is able to clean itself up properly when the garbage collector decides to free the resource's memory.
Here is an oversimplification of what happens: when the garbage collector detects that an object is garbage, the garbage collector calls the object's Finalize method (if it exists) and then the object's memory is reclaimed. For example, let's say you have the following type (in C#):
public class BaseObj {
BaseObj() {}
protected override void Finalize() {
// Perform resource cleanup code here...
// Example: Close file/Close network connection
Console.WriteLine("In Finalize.");
}
}
Now you can create an instance of this object by calling:
BaseObj bo = new BaseObj();
Some time in the future, the garbage collector will determine that this object is garbage. When that happens, the garbage collector will see that the type has a Finalize method and will call the method, causing "In Finalize" to appear in the console window and reclaiming the memory block used by this object.