Why call Dispose() before main() exits? - c#

My .net service cleans up all its unmanaged resources by calling resourceName.Dispose() in a finally block before the Main() loop exits.
Do I really have to do this?
Am I correct in thinking that I can’t leak any resources because the process is ending? Windows will close any handles that are no longer being used, right?

There is no limit to the types of resources that may be encapsulated by an object implementing IDisposable. The vast majority of resources encapsulated by IDisposable objects will be cleaned up by the operating system when a process shuts down, but some programs may use resources the operating system knows nothing about. For example, a database application which requires a locking pattern that isn't supported by the underlying database might use one or more tables to keep track of what things are "checked out" and by whom. A class which "checks out" resources using such tables could ensure in its Dispose method that everything gets checked back in, but if the program shuts down without the class having a chance to clean up the tables, the resources guarded by that table would be left dangling. Since the operating system would have no clue what any of those tables mean, it would have no way of cleaning them up.

It's probably okay to skip this, in that specific case.
The first thing to understand is that while ending the process should by itself be enough to cleanup most things, it's possible for some unmanaged resources to be left in a bad or unclosed state. For example, you might have an app that is licensed per seat, and when the app closes you need to update a database record somewhere to release your license. If a process terminates incorrectly, nothing will make that update happen, and you could end up locking people out of your software. Just because your process terminates isn't an excuse not to do cleanup.
However, in the .Net world with the IDisposable pattern you can get a little more insurance. When the process exits, all remaining finalizers will run. If the Dispose() pattern is implemented properly (and that's a bigger "if" than it should be), the finalizers are still there to take care of any remaining unmanaged resources for their objects...
However, it's good practice to always be in the habit of correctly disposing these things yourself. And FWIW, just calling .Dispose() is not enough to do this correctly. Your .Dispose() call must be included as part of a finally block (including the implicit finally block you get with a using statement).

Related

Lucene .Net, do i need to close IndexWriter

We are having locking issues with Lucene .Net throwing a LockObtainFailedException. It is a multi tenanted site and each customer gets their own physical search index on disc, and a static list of IndexWriters is used, one per index to control changes.
We call the following functions on the IndexWriter
AddDocument();
DeleteDocuments();
DeleteAll();
Optimize();
Commit();
I have noticed that we never call Close() or Dispose() on the IndexWriter, and wanted to know if this was good practice and could be the cause of the issues.
Thanks Dave
The docs say yes, but only when you're killing off the application itself - otherwise, no. Here's the docs for IndexWriter.Dispose in Lucene.Net 4.8:
Commits all changes to an index, waits for pending merges to complete,
and closes all associated files.
This is a "slow graceful shutdown" which may take a long time ...
Note that this may be a costly operation, so, try to re-use a single
writer instead of closing and opening a new one. See Commit() for
caveats about write caching done by some IO devices.
https://github.com/apache/lucenenet/blob/master/src/Lucene.Net/Index/IndexWriter.cs#L996
So, you should call .Dispose(), but, typically only once when you're shutting down the app. It is not however clear whether you need to Dispose() its underlying objects.
You're already calling .Commit(), which they recommend instead. I would guess your problem is actually related to threading. I'm just learning Lucene, but if I were in your position I'd try putting a standard .Net lock around any write calls to Lucene, so that only one thread has access to writes at a time. If it solves your issue, you know it was threading.
Locks are awfully painful, and Lucene writes may take a long time, so if the lock solves this issue it may introduce other problems like 2 threads attempting to write and one hanging or failing depending on how your code is written. If that does arise you'd probably want to implement a Write Queue so threads can quickly hand off what they'd like written to a cheap data structure like ConcurrentQueue, and then have those write ops startup the write operation if none is running, and keep dequeuing until everything's written out - then back to sleep.
To use Close/Dispose when you don't need the object any longer is always a good idea. There is a reason why a developer exposes these methods. Typically, the documentation give additional hints when to use these methods.
I also advise to use every IDisposeable-object in a using-block, which just calls Dispose().
This gives objects the ability to clean up and free resources. In case of framework-objects this isn't really important since the garbage collector will care sooner or later, but in case of system-objects or handles like file-system handles Dispose becomes important. These handles might stay open.
In the case of the Lucene IndexWriter I'm not perfectly sure, but when it uses a file for its index (which is what I assume), then you have a reason why Dispose should be called.
When handles/connections/etc stay open it can lead to such exceptions. So, yes, you should use Close()/Dispose()

Cleanup before termination?

This question has been bugging me for a while: I've read in MSDN's DirectX article the following:
The destructor (of the application) should release any (Direct2D) interfaces stored...
DemoApp::~DemoApp()
{
SafeRelease(&m_pDirect2dFactory);
SafeRelease(&m_pRenderTarget);
SafeRelease(&m_pLightSlateGrayBrush);
SafeRelease(&m_pCornflowerBlueBrush);
}
Now, if all of the application's data is getting released/deallocated at the termination (source) why would I go through the trouble to make a function in-order-to/and release them individually? it makes no sense!
I keep seeing this more and more over the time, and it's obviously really bugging me.
The MSDN article above is the first time I've encountered this, so it made sense to mention it of all other cases.
Well, since so far I didn't actually ask my questions, here they are:
Do I need to release something before termination? (do explain why please)
Why did the author in MSDN haven chosen to do that?
Does the answer differ from native & managed code? I.E. Do I need to make sure everything's disposed at the end of the program while I'm writing a C# program? (I don't know about Java but if disposal exists there I'm sure other members would appreciate an answer for that too).
Thank you!
You don't need to worry about managed content when your application is terminating. When the entire process's memory is torn down all of that goes with it.
What matters is unmanaged resources.
If you have a lock on a file and the managed wrapper for the file handler is taken down when the application closes without you ever releasing the lock, you've now thrown away the only key that would allow access to the file.
If you have an internal buffer (say for logging errors) you may want to flush it before the application terminates. Not doing so would potentially mean the fatal error that caused the application to end isn't logged. That could be...bad.
If you have network connections open you'll want to close them. If you don't then the OS likely won't do it for you (at least not for a while; eventually it might notice the inactivity) and that's rather rude to whoever's on the other end. They may be continuing to listen for a response, or continuing to send you information, not knowing that you're not there anymore.
Now, if all of the application's data is getting released/deallocated
at the termination (source) why would I go through the trouble to make
a function in-order-to/and release them individually?
A number of reasons. One immediate reason is because not all resources are memory. Only memory gets reclaimed at process termination. If some of your resources are things like shared mutexes or file handles, not releasing those resources could mess up other programs or subsequent runs of your program.
I think there's a more important, more fundamental reason though. Not cleaning up after yourself is just lazy, sloppy programming. If you are lazy and sloppy in cleanup at termination, are you lazy and sloppy at other times? If your tendancy is to be lazy and sloppy and only override that tendancy in specific areas where you're cognizant of potential problems, then your tendancy is to be lazy and sloppy. What if there are potential problems you're not cognizant of? How can you rely on your overall philosophy of lazy, sloppy programming to write correct, robust programs?
Don't be that guy. Clean up after yourself.

Why doesn't CLR handle the cleanup code?

I have just started with the .NET framework. Today, I was taught about the IDisposable interface and the dispose() method. I was taught a few things regarding it:
dispose() should contain the cleanup code corresponding to an object(like closing any resources occupied by any objects - files or database connections,etc.)
I was also told that in case we don't do it in the dispose() method, the same could be done in the destructor, but that doesn't ensure immediate execution, and we are left to the mercy of GC.
And if at all we don't provide any cleanup code at all, the GC will forcefully terminate all connections to resources that our objects were holding. Hence, we should handle the cleanup code ourselves.
But I was curious as to why doesn't CLR handle this on it's own? It takes care of Memory Management, it takes care of Garbage Collection. So, it should very well know which Object holds onto which resource(s) and when that Object dies off. So, it should be capable of de-allocating those resources as well?
I asked a few people about it. The answer I was given was that it is because we need to close it gracefully, where as GC closes it forcefully. Is it actually the reason?
In .NET there's much more than managed code that the GC knows about. There's like a huge volume of unmanaged code involved: all the file handles, database connections, network sockets, ... all this is plain ol' unmanaged Win32 code. You can't even believe that in almost every single BCL function you are calling from your pretty C# application, you will be hitting like tons of unmanaged functions written in C++ (and may God forbid VB6) and buried deep into the internals of the OS itself. All those functions are allocating unmanaged memory, handles, ... The managed world doesn't know what happens there.
For example every single time you open a file (FileStream) you are basically calling (behind the scenes of course) the CreateFile unmanaged Win32 function. This function allocates an unmanaged file handle directly from the file system. .NET and the GC has strictly no way of tracking this unmanaged code and everything it does. That's why those classes implement the IDisposable interface. So that you could always wrap their instances in using statements and ensure that the Dispose method is always called, even in the event of an exception, and this as soon as possible. The Dispose method will take care of calling another unmanaged function to clean the mess it created.
So basically the way you could think about the IDisposable interface is the following:
The day when we have an operating system written in a fully managed language (something like Midori for example from Microsoft Research) we will probably no longer need IDisposable as the GC will be able to completely replace it as it will have knowledge of everything that happens within this system.
The point of IDisposable and Dispose() is that you should clean up unmanaged memory. That's memory .NET didn't allocate, which came from outside sources and thus the GC cannot know about it. So it cannot clean it up for you automatically. Essentially that's precisely the difference between managed and unmanaged memory ;-)
Generally you should implement Dispose() to clean up whatever unmanaged resources your class uses and implement the finalizer to call Dispose() too. The finalizer is just a safeguard, though. It will make sure that those resources get cleaned up eventually, if the caller forgets to dispose of your class properly.
The IDisposable interface is there to provide you a way to clean up un-managed resources. The CLR only manages your managed resources for you.
In other words, the CLR only knows how to clean up the things that it manages. If you open connections to the rest of the system (like opening files, database connections, etc.), those are your responsibility and you need to tell the CLR how you want it to clean those up for you.
It can only take care of memory management for .NET objects. Any code that needs to use unmanaged resources (because it interacts with a C++ library, for example) falls outside the garbage collector's bailiwick. All that code needs to be told when to release its resources the old-fashioned way.
There's no way for the .Net framework (and the GC) to know how to release a un-managed resource. All it can do, is destroy the reference your managed code has to the resource. It is a lot better to actually call .Close() on a connection to your database server (thereby telling it that the connection should go back into the poll of available connection), than just destroying the reference, and letting it timeout on it's own after a set amount of seconds.
So whenever possible, use the IDisposable interface when referencing un-managed resources!
IDisposable is used when you don't want the GC to handle that particular artifact. The most common example are connections, or file handles. You don't want to wait for the GC to run before releasing a file, or to close a connection to the database, since you don't know when that will happen.
Most people associate IDisposable with unmanaged resources, which is mostly accurate, but fail to remember that finalizers are the proper .NET way to handle those. IDisposable provides a way of deterministicly disposing if that is important to your program.
The IDisposable interface is simply a convention to allow you to deterministically dispose of managed and unmanaged resources. It alone doesn't replace garbage collection or do anything involving the garbage collector itself.
It is more apparent with unmanaged resources because unless these are handled (either in a finalizer or with deterministic disposal) they will remain as a memory leak until the process ends. With managed memory, if you don't deterministically dispose of the items they will be undeterministically collected (assuming eventual eligibility for collection) by the GC, because they are managed (this is also the reason why the dispose pattern doesn't include managed items in the finalizer route).
IDisposable itself doesn't do anything, it is just a recognised interface (and is supported in code with the using keyword) that people expect to find when handling items that use consumable resources, unmanaged memory, external items, etc.
The CLR cannot possibly know when an external item is finished with. That is entirely dependent on the flow of your application. If you happen to also not know when to dispose an object, the finalizer syntax is useful. If you implement a finalizer on a custom class, the garbage collection process will run this finalizer just prior to final collection. This is your last chance to tidy up after yourself.
we use Dispose in order to dispose unmanaged resssource as file access or connection database, because GC don't have information about this unmanaged ressource.
you can also use Finalize, but it's not performant because you save your ressource in finalisation structure, and GC pass in the end of dispose cycle by this finalisation structure, and it's not performant

Static Deconstructor

I have class instantiated in a web service that, in a static member, holds on to some resources. If I was not statically holding on to these resources, I'd probably access them through some IDisposable object where I could release the resources on Dispose. Regardless of whether or not holding on to this session is a good idea, does .NET provide any way to call any clean up code when a type is statically deconstructed?
PLEASE DO NOT ANSWER THIS QUESTION WITH ANYTHING LIKE "STOP HOLDING RESOURCES IN A STATIC MEMBER VARIABLE". I understand the drawbacks to holding on to this information statically and am willing to accept the consequences (we're using it to cut processing time from 58 hours to 4 hours for some batch processing that we do). The question specifically is: given this situation, is there anyway for me to nicely clean up those resources?
EDIT:
I understand that the class will live for the rest of the process, but with static constructors .NET gives you the opportunity to do something when that type is loaded into memory. Can you do anything on the opposite end?
There actually is no way to do it from managed code. What you want is to handle your assembly being unloaded, but that doesn't happen under most circumstances when you want it to.
In more detail:
There is an AppDomain.DomainUnload event ( http://msdn.microsoft.com/en-us/library/system.appdomain.domainunload.aspx ) you can handle. This handles when your application domain gets unloaded from its hosting process (say ASP.NET).
However, if you are an EXE, or the hosting EXE is being recycled, this will not be raised. If you set up correctly, you might be able to handle the native DLL_PROCESS_DETACH and bounce that back to managed code, but because of the loader lock you will have to be very careful what you do from that context (anything that triggers an assembly load will deadlock).
You can read this for some insight on what cleanup is requited (hint: not much): http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx
Basically, the only thing you need to worry about is flushing buffers to disk, and if you need to do anything more complex, you have already screwed up. malloc(), and therefore new() could crash your program instantly. This applies to managed code as well.
The question does not really make sense, static lives for the lifetime of the process, when a process ends then everything is cleaned up by the OS. A process cannot continue to use resources if it is not running any longer.
When is the last point this static state is going to be important? At this moment, you should destruct it.
Destruct might mean something like "release some unmanaged memory, write out a cache to the database and set the static variable to null".
The last point of access will mean different things in different applications. In an ASP.NET application, you cannot reliably determine this point. It comes when the Application_End event or the AppDomain.Unload events fire, whichever comes first. The same in WCF. In a WinForms app you would to it after the main form has closed or as the last line of the main application.
In any case you need to do the cleanup yourself.
Alternative: You can encapsulate your state into a finalizable object. It will be cleaned up on AppDomain unload. If you write a so called critical finalizer you are pretty much guaranteed that your cleanup will execute.
You cannot destruct something that hasn't been instantiated.
I think you should use Singleton pattern instead of holding all data statically.
If the objects you are storing as static members properly implement IDisposable, then the .net runtime should take care of any resources when the app unloads. If any of the objects do not do this, then I suggest you create wrapper classes that implement IDisposable so that you can clean up after yourself.
IDisposable on MSDN

Why are there finalizers in java and c#?

I'm not quite understanding why there are finalizers in languages such as java and c#. AFAIK, they:
are not guaranteed to run (in java)
if they do run, they may run an arbitrary amount of time after the object in question becomes a candidate for finalization
and (at least in java), they incur an amazingly huge performance hit to even stick on a class.
So why were they added at all? I asked a friend, and he mumbled something about "you want to have every possible chance to clean up things like DB connections", but this strikes me as a bad practice. Why should you rely on something with the above described properties for anything, even as a last line of defense? Especially when, if something similar was designed into any API, said API would get laughed out of existence.
Well, they are incredibly useful, in certain situations.
In the .NET CLR, for example:
are not guaranteed to run
The finalizer will always, eventually, run, if the program isn't killed. It's just not deterministic as to when it will run.
if they do run, they may run an arbitrary amount of time after the object in question becomes a candidate for finalization
This is true, however, they still run.
In .NET, this is very, very useful. It's quite common in .NET to wrap native, non-.NET resources into a .NET class. By implementing a finalizer, you can guarantee that the native resources are cleaned up correctly. Without this, the user would be forced to call a method to perform the cleanup, which dramatically reduces the effectiveness of the garbage collector.
It's not always easy to know exactly when to release your (native) resources- by implementing a finalizer, you can guarantee that they will get cleaned up correctly, even if your class is used in a less-than-perfect manner.
and (at least in java), they incur an amazingly huge performance hit to even stick on a class
Again, the .NET CLR's GC has an advantage here. If you implement the proper interface (IDisposable), AND if the developer implements it correctly, you can prevent the expensive portion of finalization from occuring. The way this is done is that the user-defined method to do the cleanup can call GC.SuppressFinalize, which bypasses the finalizer.
This gives you the best of both worlds - you can implement a finalizer, and IDisposable. If your user disposes of your object correctly, the finalizer has no impact. If they don't, the finalizer (eventually) runs and cleans up your unmanaged resources, but you run into a (small) performance loss as it runs.
Hmya, you are getting a picture painted here that's a bit too rosy. Finalizers are not guaranteed to run in .NET either. Typical mishaps are a finalizer that throws an exception or a time-out on the finalizer thread (2 seconds).
That was a problem when Microsoft decided to provide .NET hosting support in SQL Server. The kind of application where restarting the app to solve resource leaks isn't considered a viable workaround. .NET 2.0 acquired critical finalizers, enabled by deriving from the CriticalFinalizerObject class. The finalizer of such a class must adhere to the rulez of constrained execution regions (CERs), essentially a region of code where exceptions are suppressed. The kind of things you can do in a CER are very limited.
Back to your original question, finalizers are necessary to release operating system resources other than memory. The garbage collector manages memory very well but doesn't do anything to release pens, brushes, files, sockets, windows, pipes, etc. When an object uses such a resource, it must make sure to release the resource after it is done with it. Finalizers ensure that happens, even when the program forgot to do so. You almost never write a class with a finalizer yourself, operating resources are wrapped by classes in the framework.
The .NET framework also has a programming pattern to ensure such a resource is released early so the resource doesn't linger around until the finalizer runs. All classes that have finalizers also implement the IDisposable.Dispose() method, allowing your code to release a resource explicitly. This is often forgotten by a .NET programmer but that doesn't typically cause problems because the finalizer ensures it will eventually be done. Many .NET programmers have lost hours of sleep worrying whether or not all Dispose() calls are taken care of and massive numbers of threads have been started about it on forums. Java folks must be a happier lot.
Following up on your comment: exceptions and timeouts in the finalizer thread is something that you don't have to worry about. Firstly, if you find yourself writing a finalizer, take a deep breath and ask yourself if you're on the Right Path. Finalizers are for framework classes, you should be using such a class to use an operating resource, you'll get the finalizer built into that class for free. All the way down to the SafeHandle classes, they have a critical finalizer.
Secondly, finalizer thread failures are gross program failures. Similar to getting an OutOfMemory exception or tripping over the power cord and unplugging the machine. There isn't anything you can do about them, other than fixing the bug in your code or re-route the cable. It was important for Microsoft to design critical finalizers, they can't rely on all programmers that write .NET code for SQL Server to get that code right. If you fumble a finalizer yourself then there is no such liability, it will be you that gets the call from the customer, not Microsoft.
In java finalizers exist to allow for the clean up of external resources (things that exist outside of the JVM and can't be garbage collected when the 'parent' java object is). This has always been rare. On example might be if you are interfacing with some custom hardware.
I think the reason that finalizers in java aren't guaranteed to run is that they might not have a chance to do so at program termination.
One thing you might do with a finalizer in 'pure' java is use it to test termination conditions- for example to check that all connections are closed and report an error if they are not. You aren't guaranteed that the error will be always caught but it will likely be caught at least some of the time which is enough to reveal a bug.
Most java code has no call for finalizers.
If you read the JavaDoc for finalize() it says it is "Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. A subclass overrides the finalize method to dispose of system resources or to perform other cleanup."
http://java.sun.com/javase/6/docs/api/java/lang/Object.html#finalize
So that's the "why". I guess you can argue whether their implementation is effective.
The best use I've found for finalize() is to detect bugs with freeing pooled resources. Most leaked objects will get garbage collected eventually and you can generate debug information.
class MyResource {
private Throwable allocatorStack;
public MyResource() {
allocatorStack = new RuntimeException("trace to allocator");
}
#Override
protected void finalize() throws Throwable {
try {
System.out.println("Bug!");
allocatorStack.printStackTrace();
} finally {
super.finalize();
}
}
}
They're meant for freeing up native resources (e.g. sockets, open files, devices) that can't be released until all references to the object have been broken, which is something that a particular caller would (in general) have no way of knowing. The alternative would be subtle, impossible-to-trace resource leaks...
Of course, in many cases as the application author you'll know that there's only one reference to the DB connection (for example); in which case finalizers are no substitute for closing it properly when you know you're finished with it.
In .Net land, t is not guaranteed when they run. But they will run.
Are you refering to Object.Finalize?
According to msdn, "In C# code, Object.Finalize cannot be called or overridden". In fact, they recommend using the Dispose method because it is more controllable.
There's an additional complication with finalizers in .NET. If the class has a finalizer and does not get Dispose()'d, or Dispose() does not suppress the finalizer, the garbage collector will defer collecting until after compacting generation 2 memory (the last generation), so the object is "sort of" but not quite a memory leak. (Yes, it will get cleaned up eventually, but quite possibly not until application termination.)
As others have mentioned, if an object holds non-managed resources, it should implement the IDisposable pattern. Developers should be aware that if an object implements IDisposable, then it's Dispose() method should always be called. C# provides a way to automate this with the using statement:
using (myDataContext myDC = new myDataContext())
{
// code using the data context here
}
The using block automatically calls Dispose() on block exit, even exits by return or exceptions being thrown. The using statement only works with objects that implement IDisposable.
And beware another confusion point; Dispose() is an opportunity for an object to release resources, but it does not actually release the Dispose()'d object. .NET objects are elligible for garbage collection when there are no active references to them. Technically, they can't be reached by any chain of object references, starting from the AppDomain.
The equivalent ofdestructor() in C++ is finalizer() in Java.
They are invoked when the life cycle of an object is about to end.

Categories