Declaring and disposing a local variable in a function/method in .Net - c#

Until recently it never really bothered me as to how to best declare and dispose of a local variable but I thought I'd ask once and for all and get some feedback as it's starting to bug me more and more these days.
When creating a function/method that creates a local object, which method is best to create and dispose of the object.
For simplicity sake, assume that the method of the object being called will never generate an exception i.e. ConvertThisToString
private string myFirstFunction()
{
MyDataType myObject = null;
try
{
myObject = new MyDataType();
return myOjbect.ConvertThisToString();
}
finally
{
myObject = null;
}
}
or
private string mySecondFunction()
{
MyDataType myObject = new MyDataType();
return myOjbect.ConvertThisToString();
}
Are both functions ok and is it just about coding preferences or is there one method that's better than the other? Why?
My opinion is that one always requires the try/catch in order to nullify the object, which might be an overkill of try/catch for nullifying's sake, while the other method doesn't call any explicit way to destroy the object, which might be to reliant on .NET GC to release it from memory.
Should I be using the "using" statement instead?
Well, this is probably an incorrect statement. Is a local object immediately destroyed and disposed of when leaving a function or will it be cleared at a later stage by the GC management or other.
Thanks for feedback.
Thierry
UPDATED:
Removed the catch block as it caused confusion in my question. Should haven't been there in the first place since I did say, no error would ever occur.

That's very wrong.
Don't swallow exceptions.
Assigning a variable to null at the end of its scope will not help the GC at all.
If your object actually has expensive resources, it should implement IDisposable (correctly!), and you should dispose it using a using statement (but only when you're finished with it!)

You don't need to assign to null. When the object leaves scope, it will automatically be eligible for GC. There is no need to do anything special.
Basically, just write the second, simple version.
Should I be using the "using" statement instead?
If your object is wrapping resources (not memory allocated via new ..., but native resources) and implements IDisposable, then yes, you should use the using statement to guarantee those are cleaned up.
Is a local object immediately destroyed and disposed of when leaving a function or will it be cleared at a later stage by the GC management or other.
It will become eligible to be collected. At some point in the future, the GC will clean it up, but the time when this happens in indeterminant.

The best approach here is the Using statement.
something like this:
private string myFirstFunction()
{
using(MyDataType myObject = new MyDataType())
{
return myObject.ConvertThisToString();
}
}
this will dispose the object after execution.

As with almost everything, it all depends on what object you are using. If the object you are creating implements IDisposable then you would be best served to place in a using (typically). Outside of that most objects will get cleaned up by the garbage collector. IF you are the producer of a class that accesses COM objects then as the producer you should have provided a away for a proper cleanup, e.g. implement the IDisposable interface and handle the Dispose() correctly. As others have commented swallowing exceptions or even try/catching EVERY method doesn't seem like a reasonable or good idea. If a call you are making has the potential of throwing an exception and you have unmanaged or leaky objects then you should handle via a try/finally or a using (again, if appropriate).

You don't need to use a try/catch/finally to set a variable to null. The .NET GC will clear up any unreferenced classes when a method ends in it's own time.
If you are doing something really intensive (more so than your sample shows) then you can set the variable reference to null as a pointer to the GC that this is no longer referenced. This will only make a difference to your program if you are doing something which ends up marking the variable reference for Gen2 collection and then you do more stuff which prevents the GC collecting your variable (because the scope has not been left - in this case the method).
This is a bit of an extreme case as the .NET GC is designed to remove this aspect of programming from your daily concern, and regardless, it should get cleared up when the scope ends - it might just a bit longer.
You use 'using' if the referenced object implements IDisposable, and you do this typically to release unmanaged resources - though there may be other reasons why a class implements this interface.
Your first method is total overkill... it should just be as described in MySecondFunction(), and just don't swallow exceptions (I'm referring to the empty catch block) like that - because it leads to buggy, unmaintanable code! :)

Related

Variables with function scope

How the CLR handles local variables with function scope in case an exception is thrown.
is it a must to use the finally block or the variable is disposed once the flow leaves the function
below is a small example
protected void FunctionX()
{
List<Employee> lstEmployees;
try
{
lstEmployees= new List<Employee>();
int s = lstEmployees[1].ID; // code intended to throw exception
}
catch (Exception ex)
{
ManageException(ex, ShowMessage); //exception is thrown here
}
finally { lstEmployees= null; } // Is the finally block required to make sure the list is cleaned
}
To answer your specific question, no, the finally block you've listed is not required.
Assigning null to a reference variable does not actually do anything, as garbage collection is non-deterministic. As a simplistic explanation, from time to time, the garbage collector will examine the objects within the heap to determine if there are any active references to them (this is called being "rooted"). If there are no active references, then these references are eligible for garbage collection.
Your assignment to null is not required, as once the function exits, the lstEmployees variable will fall out of scope and will no longer be considered an active reference to the instance that you create within your try block.
There are certain types (both within .NET and in third-party libraries) that implement the IDisposable interface and expose some deterministic cleanup procedures through the Dispose() function. When using these types, you should always call Dispose() when you're finished with the type. In cases where the lifetime of the instance shouldn't extend outside of the lifetime of the function, then you can use a using() { } block, but this is only required if the type implements IDisposable, which List<T> (as you used in your example) does not.
Don't be worried about the objects cleanup, that's why the .NET and most modern languages provide the garbage collection functionality in runtime.
If your object has a handle to unmanaged resource do that cleanup.
Some of the other answers are slightly misleading here.
In fact, the garbage collector has got (almost) nothing to do with the variable lstEmployees. But it never needs to be set to null, neither in normal code flow nor after an exception is thrown.
Setting references to null to free the object they point they point to is almost never required, especially not for local objects.
As a consequence, the garbage collector won’t care about the exception either.
On the other hand, unmanaged resources which aren’t handled by the CG do always require manual cleanup (via the Dispose method of the IDisposable interface). To make sure that such resources are returned after an exception was thrown, you indeed need the finally clause. Or, if you don’t intend to handle the exception locally, you can replace the try … finally by a using clause:
using (someUnmanagedResource) {
// … use the resource …
}
// Will implicitly call someUnmanagedResource.Dispose() *whatever happens*!
.NET languages are garbage collected, which means that objects lifetimes are kept track of, so the garbage collection will get rid of your list when it finds no more object references to it.
Not at all. When the variable is out of scope, the garbage collector will take care of it (when the GC decides it's time to collect all the garbage...)
The only thing you have to take in account is that maybe you don't want to wait for the GC to do its job, so resources help by an instance of a class are released (e.g. imagine you have locally created an instance that hols a reference to a database connection. The connection will be held until GC takes care of deleting the instance, and later on deleting the referenced connection, which may take a while).
In these cases, take a look at the IDisposable interface, so you can proactively free resources before your instances are removed by the GC.
.NET's garbage collector will handle this for you. In fact, setting "lastEmployees" to null accomplishes the same thing as just exiting the function.
Any item that is no longer referenced by the root application in one form or another will be marked for collection.
In .NET, you never need to worry about cleaning up managed resource. Hence, managed.
http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx

Is it necessary to free objects in final block of try-catch block?

The question is self explanatory :
Foo objfoo;
try
{
objfoo = new Foo();
..........
.........
}
catch
{
}
finally
{
objfoo = null;
}
Is it necessary to free objects like this ?
Note: Setting a local / field to null is not freeing the value. It is instead removing a reference to the value which may or may not make it elligable for collection during the next GC cyle.
To answer the question, no it is not necessary. The JIT`er will calculate the last time a local is used and will essentially remove the local as one of the object's GC roots at that time. Nulling the local out will not speed up this process.
Raymond Chen did an excellent article on this very subject
http://blogs.msdn.com/b/oldnewthing/archive/2010/08/10/10048149.aspx
You dont need to as objFoo will be eligible for garbage collection (as per your code) once you leave the try block. objfoo =null just sets the pointer to null, if any other code had a pointer to the object then it wont be garbage collected
Assigning null to a variable will not delete the object it points to.
You don't need to worry about memory cleanup. C# will do it automatically for you, if you're using .NET.
In C#, usually not, because your objects will be freed by the Garbage Collector. Setting it to null later might even extend its lifetime because (depending how the compiler optimizes your code) it is still referenced at that point.
An exception is if the object implements IDisposable, which should be disposed using its Dispose() method. But you usually wrap those in using-blocks.
No , its not necessary , let the CLR do its job.
Unless the objects are accessing unmanaged resources (files, network shares, database connections ...) there is no need to do this, since they will be marked for garbage collection once they are out of scope.
If they are using resources (the StreamReader class for example) it's necessary to dispose of the objects yourself, but that's best accomplished by using a using statement.
Automatic Garbage Collection means you do not need to free memory resources, i.e. objects created with new.
You may need to free other resources you have allocated, eg locking mutexes and maybe context specific to your own project, for which you have the finally block.
There' typically no need to do this. If your function is about to exit then your object will automatically become eligible for garbage collection.
However, if you've got a really long function or it's going to do some blocking operation after the finally block then by setting the variable to null you make it eligible for garbage collection immediately. This might be a good idea if Foo manages a large amount of data, for example.

C# - Are objects immediately destroyed when going out of scope?

Can I trust that an object is destroyed and its destructor is called immediately when it goes out of scope in C#?
I figure it should since many common coding practices (e.g. transaction objects) rely on this behaviour, but I'm not very used to working with garbage collection and have little insight to how such languages usually behave.
Thanks.
Nope, .Net and hence C# relies on a garbage collection memory management. So destructors (which in .Net is called finalizers) are not called until GC finds it proper to destroy the objects.
Additionally: most "regular" objects in C# don't have destructors. If you need the destructor pattern you should implement the IDisposable interface with the Dispose Pattern. On disposable objects you should also make sure that the Dispose method gets called, either with the using keyword or directly calling the method.
To further (hopefully) clarify: deterministic disposal is useful in .Net e.g. when you need to explicitly free resources that is not managed by the .Net runtime. Examples of such resources are file handles, database connections, etc. It is usually important that these resources be freed as soon as they no longer are needed. Thus we cannot afford to wait for the GC to free them.
In order to get deterministic disposal (similar to the scope behavior of C++) in the non-deterministic world of the .Net GC, the .Net classes rely on the IDisposable interface. Borrowing from the Dispose Pattern, here are some examples:
First, instantiating a disposable resource and then letting the object go out of scope, will leave it up to the GC to dispose the object:
1. {
2. var dr = new DisposableResource();
3. }
To fix this we can explicitly dispose the object:
1. {
2. var dr = new DisposableResource();
3.
4. ...
5.
6. dr.Dispose();
7. }
But what if something goes wrong between line 2 and 6? Dispose will not be called. To further ensure that Dispose will finally be called regardless of any exceptions we can do the following:
1. var dr = new DisposableResource();
2. try
3. {
4. ...
5. }
6. finally
7. {
8. dr.Dispose();
9. }
Since this pattern is often needed, C# includes the using keyword to simplify things. The following example is equivalent to the above:
1. using (var dr = new DisposableResource())
2. {
3. ...
4. }
No. An object doesn't actually go "out of scope," the reference to it (i.e. the variable you use to access it) does.
Once there are no more references to a given object, that object becomes eligible for garbage collection (GC) should the need arise. Whenever the GC decides it needs to reclaim the space your no-longer-referenced object, that's when the objects finalizer will be called.
If your object is a resource (e.g. a file handle, database connection), it should implement the IDisposable interface (which obligates the object to implement a Dispose() method to clean up any open connections, etc). The best practice for you in this case would be to create the object as part of a using block, so that when this block is completed, your application will automatically call the objects Dispose() method, which will take care of closing your file/db connection/whatever.
e.g.
using (var conn = new DbConnection())
{
// do stuff with conn
} // conn.Dispose() is automatically called here.
The using block is just some syntactic sugar which wraps your interactions with the conn object in a try block, along with a finally block which only calls conn.Dispose()
There is no such thing als a C++-like destructor in C#. (There is a different concept of destructor in C#, also called a finalizer, which uses the same syntax as C++ destructors, but they are unrelated to destroying objects. They're intended to provide a cleanup mechanism for unmanaged resources.)
The garbage collector will cleanup objects sometime after they are no longer referenced. Not immediately, and there is no way to guarantee this either.
Luckily there is also no real reason why you would want to guarantee this. If you need the memory, then the GC will reclaim it then. If you don't, why care if there's still some garbage object around? It's not a memory leak: the GC can still find it and clean it up any time.
No, this isn't guaranteed. Similar to languages such as Java, in C# the garbage collector runs when it's needed (i. e. when the heap is getting too full). However, when your objects implement IDisposable, i. e. they have a Dispose() method and it has to be called, then you can take advantage of the using keyword:
using (var foo = new DisposableObject()) {
// do something with that
}
That way Dispose() will be called immediately when leaving that using block.
Note: IDisposable is found in many types, most notably GDI+ but also database connections, transactions, etc. so it may really be the right pattern here.
Note 2: Behind the scenes above block will get translated into a try/finally block:
var foo = new DisposableObject();
try
{
// do something with that
}
finally
{
foo.Dispose();
}
But that translation is done by the compiler and very handy for not forgetting to call Dispose().
I don't think you should rely on garbage collectors in this way. Even if you deduct how they operate it might very well be that in the next release they've reimplemented it.
In any case, objects are not garbage collected the moment you unreference them. Typically they are collected until some threshold is reached and then they are released.
Especially in java programs this is very noticeable when you look at the memory consumption on the task manager. It grows and grows and all of a sudden every minute it drops again.
No. If you refer to CLI specification (p. 8.9.6.7 about Finalizers) http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf you can find the following
the CLI should ensure that finalizers are called soon after the instance becomes
inaccessible. While relying on memory pressure to
trigger finalization is acceptable, implementers should consider the use of additional
metrics
but it must not.

How do I track down where I've been leaking IDisposable objects from?

I've been debugging some code recently that was a bit memory leaky. It's a long running program that runs as a Windows service.
If you find a class wearing an IDisposable interface, it is telling you that some of the resources it uses are outside the abilities of the garbage collector to clean up for you.
The reason it is telling you this is that you, the user of this object, are now responsible for when these resources are cleaned up. Congratulations!
As a conscientious developer, you are nudged towards calling the .Dispose() method when you've finished with the object in order to release those unmanaged resources.
There is the nice using() pattern to help clean up these resources once they are finished with. Which just leaves finding which exact objects are causing the leakyness?
In order to aid tracking down these rogue unmanaged resources, is there any way to query what objects are loitering around waiting to be Disposed at any given point in time?
There shouldn't be any cases where you don't want to call Dispose, but the compiler cannot tell you where you should call dispose.
Suppose you write a factory class which creates and returns disposable objects. Should the compiler bug you for not calling Dispose when the cleanup should be the responsibility of your callers?
IDisposable is more for making use of the using keyword. It's not there to force you to call Dispose() - it's there to enable you to call it in a slick, non-obtrusive way:
class A : IDisposable {}
/// stuff
using(var a = new A()) {
a.method1();
}
after you leave the using block, Dispose() is called for you.
"Is there any way to detect at the end of the program which objects are loitering around waiting to be Disposed?"
Well, if all goes well, at the end of the program the CLR will call all object's finalizers, which, if the IDisposable pattern was implemented properly, will call the Dispose() methods. So at the end, everything will be cleared up properly.
The problem is that if you have a long running program, chances are some of your IDiposable instances are locking some resources that shouldn't be locked. For cases like this, user code should use the using block or call Dispose() as soon as it is done with an object, but there's really no way for a anyone except the code author to know that.
You are not required to call the Dispose method. Implementing the IDisposable interface is a reminder that your class probably is using resources such as a database connection, a file handle, that need to be closed, so GC is not enough.
The best practice AFAIK is to call Dispose or even better, put the object in a using statement.
A good example is the .NET 2.0 Ping class, which runs asynchronously. Unless it throws an exception, you don't actually call Dispose until the callback method. Note that this example has some slightly weird casting due to the way Ping implements the IDisposable interface, but also inherits Dispose() (and only the former works as intended).
private void Refresh( Object sender, EventArgs args )
{
Ping ping = null;
try
{
ping = new Ping();
ping.PingCompleted += PingComplete;
ping.SendAsync( defaultHost, null );
}
catch ( Exception )
{
( (IDisposable)ping ).Dispose();
this.isAlive = false;
}
}
private void PingComplete( Object sender, PingCompletedEventArgs args )
{
this.isAlive = ( args.Error == null && args.Reply.Status == IPStatus.Success );
( (IDisposable)sender ).Dispose();
}
Can I ask how you're certain that it's specifically objects which implement IDisposable? In my experience the most-likely zombie objects are objects which have not properly had all their event handlers removed (thereby leaving a reference to them from another 'live' object and not qualifying them as unreachable during garbage collection).
There are tools which can help track these down by taking a snapshot of the managed heap and stacks and allowing you to see what objects are considered in-use at a given point in time. A freebie is windbg using sos.dll; it'll take some googling for tutorials to show you the commands you need--but it works and it's free. A more user-friendly (don't confused that with "simple") option is Red Gate's ANTS Profiler running in Memory Profiling mode--it's a slick tool.
Edit: Regarding the usefulness of calling Dispose--it provides a deterministic way to cleanup objects. Garbage Collection only runs when your app has ran out of its allocated memory--it's an expensive task which basically stops your application from executing and looks at all objects in existance and builds a tree of "reachable" (in-use) objects, then cleans up the unreachable objects. Manually cleaning up an object frees it before GC ever has to run.
Because the method creating the disposable object may be legitimately returning it as a value, that is, the compiler can't tell how the programming is intending to use it.
What if the disposable object is created in one class/module (say a factory) and is handed off to a different class/module to be used for a while before being disposed of? That use case should be OK, and the compiler shouldn't badger you about it. I suspect that's why there's no compile-time warning---the compiler assumes the Dispose call is in another file.
Determining when and where to call Dispose() is a very subjective thing, dependent on the nature of the program and how it uses disposable objects. Subjective problems are not something compilers are very good at. Instead, this is more a job for static analysis, which is the arena of tools like FxCop and StyleCop, or perhaps more advanced compilers like Spec#/Sing#. Static analysis uses rules to determine if subjective requirements, such as "Always ensure .Dispose() is called at some point.", are met.
I am honestly not sure if any static analyzers exist that are capable of checking whether .Dispose() is called. Even for static analysis as it exists today, that might be a bit on the too-subjective side of things. If you need a place to start looking, however, "Static Analysis for C#" is probably the best place.

How to do C++ style destructors in C#?

I've got a C# class with a Dispose function via IDisposable. It's intended to be used inside a using block so the expensive resource it handles can be released right away.
The problem is that a bug occurred when an exception was thrown before Dispose was called, and the programmer neglected to use using or finally.
In C++, I never had to worry about this. The call to a class's destructor would be automatically inserted at the end of the object's scope. The only way to avoid that happening would be to use the new operator and hold the object behind a pointer, but that required extra work for the programmer isn't something they would do by accident, like forgetting to use using.
Is there any way to for a using block to be automatically used in C#?
Many thanks.
UPDATE:
I'd like to explain why I'm not accepting the finalizer answers. Those answers are technically correct in themselves, but they are not C++ style destructors.
Here's the bug I found, reduced to the essentials...
try
{
PleaseDisposeMe a = new PleaseDisposeMe();
throw new Exception();
a.Dispose();
}
catch (Exception ex)
{
Log(ex);
}
// This next call will throw a time-out exception unless the GC
// runs a.Dispose in time.
PleaseDisposeMe b = new PleaseDisposeMe();
Using FXCop is an excellent suggestion, but if that's my only answer, my question would have to become a plea to the C# people, or use C++. Twenty nested using statements anyone?
Where I work we use the following guidelines:
Each IDisposable class must have a finalizer
Whenever using an IDisposable object, it must be used inside a "using" block. The only exception is if the object is a member of another class, in which case the containing class must be IDisposable and must call the member's 'Dispose' method in its own implementation of 'Dispose'. This means 'Dispose' should never be called by the developer except for inside another 'Dispose' method, eliminating the bug described in the question.
The code in each Finalizer must begin with a warning/error log notifying us that the finalizer has been called. This way you have an extremely good chance of spotting such bugs as described above before releasing the code, plus it might be a hint for bugs occuring in your system.
To make our lives easier, we also have a SafeDispose method in our infrastructure, which calls the the Dispose method of its argument within a try-catch block (with error logging), just in case (although Dispose methods are not supposed to throw exceptions).
See also: Chris Lyon's suggestions regarding IDisposable
Edit:
#Quarrelsome: One thing you ought to do is call GC.SuppressFinalize inside 'Dispose', so that if the object was disposed, it wouldn't be "re-disposed".
It is also usually advisable to hold a flag indicating whether the object has already been disposed or not. The follwoing pattern is usually pretty good:
class MyDisposable: IDisposable {
public void Dispose() {
lock(this) {
if (disposed) {
return;
}
disposed = true;
}
GC.SuppressFinalize(this);
// Do actual disposing here ...
}
private bool disposed = false;
}
Of course, locking is not always necessary, but if you're not sure if your class would be used in a multi-threaded environment or not, it is advisable to keep it.
Unfortunately there isn't any way to do this directly in the code. If this is an issue in house, there are various code analysis solutions that could catch these sort of problems. Have you looked into FxCop? I think that this will catch these situations and in all cases where IDisposable objects might be left hanging. If it is a component that people are using outside of your organization and you can't require FxCop, then documentation is really your only recourse :).
Edit: In the case of finalizers, this doesn't really guarantee when the finalization will happen. So this may be a solution for you but it depends on the situation.
#Quarrelsome
If will get called when the object is moved out of scope and is tidied by the garbage collector.
This statement is misleading and how I read it incorrect: There is absolutely no guarantee when the finalizer will be called. You are absolutely correct that billpg should implement a finalizer; however it will not be called automaticly when the object goes out of scope like he wants. Evidence, the first bullet point under Finalize operations have the following limitations.
In fact Microsoft gave a grant to Chris Sells to create an implementation of .NET that used reference counting instead of garbage collection Link. As it turned out there was a considerable performance hit.
~ClassName()
{
}
EDIT (bold):
If will get called when the object is moved out of scope and is tidied by the garbage collector however this is not deterministic and is not guaranteed to happen at any particular time.
This is called a Finalizer. All objects with a finaliser get put on a special finalise queue by the garbage collector where the finalise method is invoked on them (so it's technically a performance hit to declare empty finalisers).
The "accepted" dispose pattern as per the Framework Guidelines is as follows with unmanaged resources:
public class DisposableFinalisableClass : IDisposable
{
~DisposableFinalisableClass()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// tidy managed resources
}
// tidy unmanaged resources
}
}
So the above means that if someone calls Dispose the unmanaged resources are tidied. However in the case of someone forgetting to call Dispose or an exception preventing Dispose from being called the unmanaged resources will still be tidied away, only slightly later on when the GC gets its grubby mitts on it (which includes the application closing down or unexpectedly ending).
The best practice is to use a finaliser in your class and always use using blocks.
There isn't really a direct equivalent though, finalisers look like C destructors, but behave differently.
You're supposed to nest using blocks, that's why the C# code layout defaults to putting them on the same line...
using (SqlConnection con = new SqlConnection("DB con str") )
using (SqlCommand com = new SqlCommand( con, "sql query") )
{
//now code is indented one level
//technically we're nested twice
}
When you're not using using you can just do what it does under the hood anyway:
PleaseDisposeMe a;
try
{
a = new PleaseDisposeMe();
throw new Exception();
}
catch (Exception ex) { Log(ex); }
finally {
//this always executes, even with the exception
a.Dispose();
}
With managed code C# is very very good at looking after its own memory, even when stuff is poorly disposed. If you're dealing with unmanaged resources a lot it's not so strong.
This is no different from a programmer forgetting to use delete in C++, except that at least here the garbage collector will still eventually catch up with it.
And you never need to use IDisposable if the only resource you're worried about is memory. The framework will handle that on it's own. IDisposable is only for unmanaged resources like database connections, filestreams, sockets, and the like.
A better design is to make this class release the expensive resource on its own, before its disposed.
For example, If its a database connection, only connect when needed and release immediately, long before the actual class gets disposed.

Categories

Resources