Are non-disposed resources freed when an object is garbage collected? - c#

I was posed this question, and while I believe I know the answer, I believe I should be 100% certain else I start spreading misinformation!
I have this object:
public class MyObj(){
private SqlConnection conn;
public MyObj(string connString){
var stream = File.Open(#"c:\\file.txt");
conn = new SqlConnection(connString);
}
}
When this object is created, a file handle is associated with the file, and a connection to a database is created. Neither has Dispose called on it as they should.
When this object goes out of scope and is eventually garbage collected, are these two resources then released, or do they remain in memory?

When this object goes out of scope and is eventually garbage collected, are these two resources then released, or do they remain in memory?
Usually some type - often somewhat hidden from the public API - has a handle on a native resource, possibly via SafeHandle, and that's what ends up releasing the resource. It's possible to write code which doesn't do this, of course, in which case the native resources would only be released on process exit through the normal OS clean-up, but I'd expect any Microsoft-provided APIs to do the right thing.
Of course, you should still dispose of resources explicitly :)

Any object that directly uses an unmanaged resource like a file handle or a database connection should always implement a finalizer that releases the unmanaged resource. When the object is garbage collected the finalizer is executed and the unmanaged resource is freed. So to answer your question:
When this object goes out of scope and is eventually garbage collected, are these two resources then released, or do they remain in memory?
Yes, the unmanaged resources will eventually be freed by the garbage collector that calls the finalizer of the object.
As you are aware of, leaving it to the garbage collector to clean up unmanaged resources is normally a bad thing. If you open and read a file you would prefer that the file is closed and available to other processes when the read has completed instead at some random future time when the garbage collector decides to release the now unused file object.
.NET provides the IDisposable interface to enable deterministic release of unmanaged resources. When you dispose a FileStream object the underlying unmanaged file handle is released and the file is closed.
An important part of implementing the IDisposable interface is that if the unmanaged resource is released via a call to Dispose then the object no longer needs to be finalized. That is why you see a call to GC.SuppressFinalize(this) when an object implements IDisposable and has a finalizer. Avoiding finalization is a good thing to reduce the amount of resources that the garbage collector has to use. Also, finalizers run within tight constraints established by the garbage collector so they are best avoided.
Note that most of the time your objects will not have a finalizer because you do not use any unmanaged resource. Instead you will get access to unmanaged resources using a managed objects like SafeHandle. In that case the object does not need a finalizer but should implement IDisposable and forward calls to Dispose to any aggregated IDisposable objects.

Short answer: They are automatic released.
Just one time, years ago, I got a inexplicable memory leak due to a object not being released.
At the time I need to put some explicit call to the garbage collector to fix the problem.
Never found the real cause, maybe a framework bug, maybe something to do with a OS resource but I can say 99.99% of time you can be free of worries about it in C#.

Related

What is the difference between the resources disposed in a finalizer to those released in dispose

This is a follow up question to this question:
Finalize/Dispose pattern in C#
So I understand that if I'm creating a class that uses unmanaged resources, I should dispose them. The answer in the linked question says that the finalizer disposes of the unmanaged resources. However, the Dispose(Boolean) method is also disposing of unmanaged resources:
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// get rid of managed resources
}
// get rid of unmanaged resources
}
So what is the difference between the disposal of the finalizer and the disposal of the dispose method?
The only reason you would use it (and its extremely controversial).
A finalizer allows the clearing an object before it will be deleted by a garbage collector. (That's to say, The GC is responsible for calling it, and clearing the object from memory) If the developer forgot to call Dispose() method of an object, then it will be possible to free the unmanaged resources and thus, avoid the leak.
There are many reasons not to, and many ways to get it wrong. In short there is seldom a reason why you need to do this, or want to do it
In addition to given answer: finalizer is is called by garbage collector when it runs.
So you can't rely on time of releasing unmanaged resources in finalizer! Because it is unknown.
Also, finalizer runs on another thread, so when garbage collection finishes, finalization may be still running! So there has to by another garbage collection, to completely get rid of an object.
So, first garbage collection call finalezrs, but object doesn't get collected (and also objects, that the object holds references to), it will be collected on the second garbage collection.
An object with finalizer goes through two phases of GC: First time, the finalizer is run and second time, the object is actually collected and the memory is freed. Apart from increasing the GC pressure and delaying the memory release back to pool, finalizers also have the feature of working with objects whose fields may not be in valid state. Also, throwing an exception on finalizer thread tears down the whole application instantly without any friendly information on what just happened.
This is why the Dispose pattern implementation always features the call to GC.SuppressFinalize which causes the finalizer not to run in case the object was already disposed and the GC can directly free the memory on first run.
Generally, using finalizers can be very complex and tricky if your application should survive critical exceptions such as out of memory or thread abort and subsequent AppDomain unloads - this is the case for applications such as SQL Server or IIS.
Long story short: Do not use finalizers unless you absolutely have to, and if you have to (e.g. using unmanaged resources), there's quite a bit of research awaiting you.
You can find more reading on this topic in the following blog posts:
Eric Lippert - When everything you know is wrong
Joe Duffy - Never write a finalizer again

finalization handle remains in the memory. how to remove this reference?

I need to optimize my application in memory usage. so I used .net performance profiler...
but some references in my application are still alive and are never collected by GC even if I force it to collect.
The reference that is alive is a "finalization handle" type.
I don't know what to do to remove this kind of reference.... please help.
This is not a memory leak, just sloppy coding on the part of the author(s) of AMProLibrary.
As you observed, the profiler is telling you that the referenced object is of type "Finalization Handle". What that means is that it is coming from the finalizer queue. The finalizer queue is what the .NET garbage collector uses to hold all objects that implement a finalizer method. The finalizer is the mechanism used to ensure that unmanaged resources are properly released during garbage collection. An object that contains unmanaged resources implements the IDisposable pattern, including the Finalize method, which is where the unmanaged resources are released. When the garbage collector processes "finalizable" objects (as indicated by the value of a bit in the object's header), it moves them into the finalizer queue. During collection, the GC iterates through the finalizer queue and calls the Finalize method on each of those objects.
What the author of the library evidently failed to do is to call GC.SuppressFinalize() from within the Dispose method. This normally removes the object from the finalizer queue by clearing the "finalizable" bit in the object's header, and indicates that the Finalize method does not need to be called.
For testing purposes, you can force the finalizers to run by calling the GC.WaitForPendingFinalizers function. For example:
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect();
However, you should not actually use code like this in a production application. Forcing a collection rarely makes sense. This will just prove the validity of the hypothesis stated above.
In general, you should not rely on the finalizer to release unmanaged resources. All objects that implement IDisposable should be explicitly disposed of by your code, either by manually calling the Dispose method or, preferably, by wrapping their creation in a using block that will automatically call Dispose when the block's scope is exited.

In C# does (new Obj()).foo() dispose of Obj when the parenthesis scope is exited?

I am happy using IDisposable and using blocks but often I find myself writing (new Obj()).Foo(); to avoid the extra instantiation code and naming etc. Does this instance hang in memory until the end of the function scope or is it disposed of directly after the enclosing parenthesis is exited...? Is there an alternative I am missing? An equivalent to implementing IDisposable for concrete objects that I want to use once and throw away?
IDisposable is not related whit when the memory allocated for the object is released. In both cases the memory is released when the Garbage Collector decides to release it.
IDisposable is used for objects that need to execute some action in order to release the resources it allocates outside them. For example if the objects open a Database connection, you must release it as soon as you don't need it anymore.
So IDisposable gives you one thing:
A way to release the resources as soon as you want, by calling the Dispose() method or using the using clause
So it's ok to do:
new Obj()).Foo();
And has no sense to make Obj implements IDisposable if it does not uses any resource that must be deallocated.
If an object implements IDisposable, it is imperative that you Dispose() the object in your own code, either explicitly (and within a try/finally construct, too!) or with the using syntax, and do not simply let the reference(s) fall out of scope.
EDIT: I feel like I used an awful lot of words to get around to explaining the most important aspect of all this, which is that the only reason an object should implement IDisposable is if it holds handles to other objects that are unmanaged (the CLR doesn't know about them) or scarce (due to resources/cost/licensing/etc.). So if an object implements IDisposable, you MUST call Dispose() YOURSELF, as soon as possible. The CLR will not do it for you. And if you implement IDisposable on your own classes, you need to be implementing a finalizer on them, too.
Simply letting a reference fall out of scope does not cause the GC to run immediately, and you have no guarantees whatsoever that a GC is going to occur any time soon. You can explicitly trigger a GC with code, but that is typically going to hurt overall performance more than help it.
If there is not much memory pressure, for instance, the CLR may wait a long time before running the GC. There just isn't a pressing need for it to run in a situation where there is light or zero contention for resources. If it ran too often, it would impact the performance of your applications negatively
The GC does not call Dispose(). The GC calls an object's finalizer if it has one. The finalizer is a special method using syntax similar to a C++ destructor, but which really is not a destructor in that sense.
So if an object implements IDisposable, but does not implement a finalizer, the GC will never release that object's resources. The object will cause both memory leaks and unresolvable resource contention.
Nor does calling Dispose() from your own code trigger a GC.
The finalizer is a last-ditch backup mechanism to try to ensure that a class holding scarce or expensive resources does eventually let go of them even if consumers of the class fail to explicitly release those resources.
IDisposable is really just a common convention, implemented with a handy well-known interface contract, to let callers generically request that any class holding scarce resources release those resources immediately.
The standard pattern is that the finalizer calls the Dispose() method (actually, it typically calls Dispose(false) and I'm intentionally ignoring that detail). The Dispose() method will release all the scarce resources, then it can call GC.SuppressFinalize() so that the GC can free the object's memory more quickly when it gets around to running.
The old tried and true "acquire late/release early" semantics apply here.
You should read up on how the GC uses multiple passes or "generations" to clean up objects with finalizers.
The GC can get rid of regular objects (objects where all the resources are managed by the CLR) in one pass. If there are no in-scope references to an object, the GC can basically just delete it.
But if an object has a finalizer (and GC.SuppressFinalize() has not been called), the GC uses at least 2 passes or generations to release the object. In the first generation, it marks the object for finalization. In the second generation (which happens the next time the GC runs), it actually calls the finalizer, and at that point the object is finally eligible to have its memory released.
The scarce/expensive resources we're talking about are typically things like network sockets, file handles, database or other server connections which may be limited or expensive or resource-intensive or all three, etc. This is also true of virtually all "unmanaged" (non .NET CLR) resources, including things like Win32 window handles, file handles, network sockets and so on. Such resources require deterministic cleanup. You need to let go of them as quick as you can, but the CLR is going to take its sweet time getting around to cleaning this stuff up. You have to do it yourself.
But if your class isn't using any of these types of scarce/expensive/"unmanaged" resources, then there is probably no reason to implement IDisposable on it at all.

How GC releases managed resources in C#

As of my knowledge i know like GC performs collection operation in order to remove unmanaged resources to release memory which is called implicit clean up. And by using 'USING' keyword we can do it explicit cleaning but my doubt is how GC releases managed resources.
You don't have to do anything special in order for GC to clean up your managed resources. GC will clean it up sometime after there are no references left to your managed resource.
If your managed resource owns unmanaged resources, you can implement the IDisposable interface and call the Dispose method, in which you'd explicitly clean up your unmanaged resources. using statement makes it very easy to use this interface, as it automatically calls Dispose when the code exists the using block, even in case of exceptions.
You might take a look at the MSDN documentation on Garbage Collection.
EDIT: based on comments above.
You could override Object.Finalize by defining a finalizer (e.g. ~MyClass()) but there is no telling when it will be called by GC. IDisposable is generally preferred. More info on Finalizer vs Dispose here.

C# language: Garbage Collection, SuppressFinalize

I'm reading "The C# Language", 4th Edition, it talks about garbage collection as below:
"BILL WAGNER: The following rule is an important difference between C# and other managed environments.
Prior to an application’s termination, destructor's for all of its objects that have not yet been garbage collected are called, unless such cleanup has been suppressed (by a call to the library method GC.SuppressFinalize, for example)."
So I have a couple of questions here:
Q1. Why .net is different from other managed environments (I suppose this is hinting Java?) here? Any particular design concern?
Q2. What will happened to objects that GC.SuppressFinalize is called?
I understand that this means GC will not call such objects' finalizer (destructor), if so, when will these objects got really destroyed, so that the allocated memory bits are returned to the heap? Otherwise there'll be Memory Leak?
What will happened to objects that GC.SuppressFinalize is called? I understand that this means GC will not call such objects' finalizer (destructor), if so, when will these objects got really destructed? otherwise there'll be Memory Leak right?
You have a misunderstanding of what finalization is for. Finalization is for cleaning up resources that are not managed memory.
Suppose you have an object of reference type that contains an integer field. That integer field just happens to be a handle to a file that was obtained by calling into unmanaged code to open the file.
Since some other program might want to access that file, it is polite to close the file as soon as possible. But the .NET runtime has no idea that this integer has any special meaning to the operating system. It's just an integer.
The way you solve this problem typically is you mark the object as implementing IDisposable, and then you call "Dispose" on the object as soon as you're done with it. Your implementation of "Dispose" then closes the file.
Note that there is nothing special going on here. It is just a convention that a method that cleans up an unmanaged resource is called "Dispose" and an object that needs to be disposed implements IDisposable. The garbage collection knows absolutely nothing about this.
So now the problem arises: what if someone forgets to call Dispose? Does the file stay open forever? (Clearly the file will be closed when the process ends, but what if the process runs for a long time?)
To solve this problem, you use a finalizer. How does that work?
When an object is about to be garbage collected, the garbage collector checks it to see if it has a finalizer. If it does, then instead of garbage collecting it, it puts it on the finalizer queue. At some unspecified point in the future, a thread runs that examines the queue and calls a special "Finalize" method on every object. After that, the object is removed from the finalization queue and marked as "hey, I've already been finalized". The object is now once again eligable for collection, and so the garbage collector eventually runs and collects the object without putting it on the finalization queue.
Clearly "Finalize" and "Dispose" frequently need to do the same thing.
But now another problem arises. Suppose you dispose an object. Now it does not need to be finalized. Finalization is expensive; it keeps a dead object alive for much longer than it needs to be. Therefore, traditionally when one disposes an object, the implementation of Dispose not only closes the unmanaged resource, it also marks the object as "this object has already been finalized, don't finalize it again". That way it tricks the garbage collector into not putting the object on the finalization queue.
So let's answer your specific questions:
What will happened to objects that GC.SuppressFinalize is called?
When the object is dead the garbage collector will simply reclaim the memory of the object without putting the object on the finalizer queue.
I understand that this means GC will not call such objects' finalizer
The GC never calls a finalizer. The finalizer thread is the only thing that calls finalizers.
when will these objects got really destructed?
It is not clear what you mean by "destructed". If you mean "when will the finalizers run?" the answer is "never" because you said to suppress finalization. If you mean "when will the memory in the managed heap be reclaimed?", the answer is "as soon as the object is identified as dead by the garbage collector". That will happen sooner than normal because the object will not be kept alive by the finalizer queue.
Q1: I suspect it's because it cares more about achieving great performance, as opposed to Java which has made quite a few sacrifices for simplicity.
Q2: Since finalizers aren't even guaranteed to be called in the first place (even if SuppressFinalize didn't exist), this should be only used for performance reasons, when you've disposed the resources already. Otherwise you should use IDisposable to dispose of resources.
Finalization != Destruction
Destructors (in the C++ sense) don't exist in .NET -- because every object, in a sense, has a "destructor", called the garbage collector. :)
What C# calls "destructors" are in fact finalizers.
Finalizers are for disposing things other than the memory allocated by the object, such as file handles, etc. Not every object, therefore, had a finalizer. The memory is always freed by the GC, so you don't get a memory leak that way.
I only know the second answer: SuppressFinalize is called when the object has already been destructed, i.e., by IDisposable.Dispose. So it shouldn't be destructed again.
This is because finalizers are a resource cleanup that occurs at a non-deterministic time. IDisposable was added to allow resource cleanup that occurs at a specific, predictable time.
EDIT: At process termination, memory leaks are immaterial. When a process terminates, its heaps are collected by Windows, so it doesn't matter if an object's memory is returned to the heap or not.
I try to answer Q2:
If your class has a finalizer (shown by the ~ClassName), then it will not be directly collected by the garbage collection, instead it will be put on the finalizer queue which will be called later. Now when finalizer is finally called it usually frees any unmanaged resources, the class created. If for any reason the user already did it, usually by calling dispose, the finalizer don't need to clean the unmanaged memory, thus calling SuppressFinalizer is necessary. Otherwise it would try to free the resources again.
So the only memory leak you will get is by any resources that you requested on creation of your class. The finalizer is just to free everything that is not already managed by the framework.
There is because once call GC.Collect()
The object with finalize will move to next generation at least once.
We can call GC.SuppressFinalize, and GC will know this object is de-reference, we can remove this object and compact heap then.
Usually, this implement with dispose pattern

Categories