Cleanup before termination? - c#

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.

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()

C# - Automatically free memory at the end of a block

So I have a program that increases the memory by 5MB per second. Since only 2GB can be allocated per application, I hit my limit at about 5 minutes after I start my program and get a System.OutOfMemoryException.
I have "done my homework" (hopefully good enough :D) and know that after the end of a block, the variables within that block are not disposed.
Ultimately, I need a way to automatically free the memory from variables used in after each block to stop the OutOfMemoryException from occurring.
P.S.: I realize there is a lot of confusion on this topic so if I made a mistake in my question, please feel free to correct me. But mostly, I would like to get this exception out of the way.
EDIT
Alright something weird happened. I copied the entire project from my desktop (where it doesn't work) to my laptop. And apparently, it works just fine on my laptop! The memory only increases MOSTLY by 500 KBps and is automatically freed 1 second later. I have no idea why, it's exactly the same project and no code was altered.
Anyone know why this happens?
Use these variables in a using statement and call GC.Collect() when done
In my experience, the most common way to leak memory in managed code is holding on to references for too long, alternatively not realizing how references are handled. A live reference will prevent garbage collection, no matter how well your code is disposing stuff.
Here is a decent article on how to figure out just what is leaking and where those references are, and you probably want to read up on the 'additional background' links as well.
Use ANTS profiler or CLRProfiler to determine which objects are taking up space and which methods are creating and holding references these object.
probably this discussion will help you to understand what is actually happening regarding memory management in .net Finalize/Dispose pattern in C#
and just in case, this is another post on how to dispose objects: the correct technique for releasing a socket/event/ummaged code with the dispose/finalize pattern
Maybe your objects should implement IDisposable so you can clean up resources when you no longer need them. This MSDN article shows how to implement it:
Digging into IDisposable

Why call Dispose() before main() exits?

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).

How to use GC.KeepAlive() and for what purpose?

How can we use GC.KeepAlive() and what is the purpose?
I transfer files from terminal (Windows-CE) to Server using Socket. The time needed for transfer is 8 minutes. After 5 minutes the Windows-CE shuts down (if touch screen not pressed)
If I use GC.KeepAlive() for this, does this solve my problem?
You very rarely need to use GC.KeepAlive - very rarely. You'd use it if you wanted to prevent the side-effect of a finalizer from occurring too early, for example. I've most often seen it used for Mutex - keeping mutex alive until the end of an app to make sure there's only one instance. (A using statement is actually better here, but that's a separate matter.)
And no, it doesn't sound like it's relevant in your situation.
From the MSDN library for .NET:
The purpose of the KeepAlive method is to ensure the existence of a
reference to an object that is at risk of being prematurely reclaimed
by the garbage collector. A common scenario where this might happen is
when there are no references to the object in managed code or data,
but the object is still in use in unmanaged code such as Win32 APIs,
unmanaged DLLs, or methods using COM.
So not this would not solve your problem. In fact it's not even related to your problem.
The only thing you can do is in the service/application running on the Windows CE, adding code that prevents the system to shutdown as long as the transfer is in progress
The screen powering down is a power-management setting on the device. It's going to happen whether or not any app is running. The GC has absolutely nothing to do with this.
If you want to prevent the power maanger from putting hte device into a low-power state, you have a few options. You can periodically call SystemIdleTimerReset in your app.
You could force the power state to something you like with SetSystemPowerState.
You could change the power manager timeouts to something more to your liking by adjusting settings at [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Power\Timeouts] (followed by a WM_SETTINGS_CHANGE broadcast IIRC).
The best "solution" is going to depend on your app requirements, your users' requirements and the power management system of the target device.

In which real life scenario you used garbage collector?

I know all the theories :
I know what is GC, when to call dispose, Finalise when it is getting called.
I would like to know, in your live project ..in which scenario have used all this.
I mean when the project
manager/client insisted you to
cleanup the memory ? When you find
any errors in the programs? Kind of
error messages or error logs? When
your program got crashed because of
unwanted memory? or any other
scenarios?
You should not care when and how GC is called. It is inteligent enough to know when to run and what objects to free.
You should also Dispose, either manualy or using "using" all objects, that implement IDisposable. You will then prevent many errors with un-managed resources, like files.
And if you are running out of memory, then there is something wrong with your algorithm or code itself. Manualy calling GC.Collect is heavily discuraged, especialy in production code.
As a rule of thumb, you need to implement IDisposable if you aggregate a disposable object, or if you hold on to an unmanaged resource. Cleanup is done differently for these two scenarios. Otherwise, keep it simple, don't litter your code with dotnetisms
Similar question here
Memory leaks cause crashed up servers. Cause and effect.
Ressource management is something you just havce to do. It is not 'my client insisted I free my memory'. It is simply good practice. Not all applications may crash and the user just restarts them - there is one or other server application out there.
If you start building your programming libraries, ressource management and concurrency should be your top priority, otherwise you will never be up to speed implementing any solution.
hth
Mario

Categories