This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does the tilde (~) mean in C#?
class ResourceWrapper
{
int handle = 0;
public ResourceWrapper()
{
handle = GetWindowsResource();
}
~ResourceWrapper() //this line here
{
FreeWindowsResource(handle);
handle = 0;
}
[DllImport("dll.dll")]
static extern int GetWindowsResource();
[DllImport("dll.dll")]
static extern void FreeWindowsResource(int handle);
}
What does the tilde do on the line indicated.
I thought that it was the bitwise NOT operator, infact I don't really understand that whole block there, (the commented line and the parentheses blovk after it), it isn't a methd, or a parameter or anything, what is it and why is there a tilde before it?
That is destructor. It takes care that all resources are released upon garbage collection.
This implements the finalizer (the Finalize method) of the class.
Normally you should not implement a finalizer.
E.g. do this for classes that hold external unmanaged resources but be sure to implement the IDisposable Pattern in this case too.
Like in C++, ~ClassName is the destructor method. It gets called in C# when the object in question gets cleaned up by the garbage collector. Unlike in C++ where there are deterministic times when the destructor is called, there is no way of predicting when it will be called (or even if it will be called) in C#.
What you are probably looking for is the IDisposable pattern, which provides a much better approach to this.
That is a Destructor. It gives you implicit control over releasing resources. That is, it is called by the Garbage Collector. If you want explicit control over the release of resources, you can implement IDisposable Check out Implementing Finalize and Dispose to Clean Up Unmanaged Resources. The Framework Design Guidelines also has more information.
Ack, i just found the answer and can't see how to delete my question. it specifies the destructor of the class
i have no clue about C#, but from what the code does, this looks like a deconstructor, saying
free the resource referenced by handle
set handle to 0 to be sure
would kind of go together with the notion of "not" as well ... :)
i may be wrong though ...
greetz
back2dos
Related
I have found on our code base code like this:
if (disposing)
{
....
}
Marshal.ReleaseComObject(comObject)
As the comObject is in fact a .Net object (a RCW, right?) is it safe to call it from the Finalizer?
Is it possible that it has been already released?
As Hans Passant said:
No, that is not safe, an RCW already has its own finalizer. Which
first of all makes the code completely unnecessary. More severely,
since finalization order is not deterministic you might be calling
ReleaseComObject() on an object that is already destroyed
So the call must be inside the if (disposing).
This question already has answers here:
What is IDisposable for?
(6 answers)
Closed 7 years ago.
I come from a C++ background and have trouble understanding the point of IDisposable objects (and the point of many other things in .NET). Why is a Dispose function necessary in the first place? Whatever it does, why not do that in the destructor of the class? I understand it cleans up managed resources, but isn't that what a destructor is supposed to do? I understand that
Using ( var obj = new SomeIDisposableObject )
{
// ...
}
is the equivalent of
var obj = new SomeIDisposableObject;
// ...
obj.Dispose();
but how does that save any typing? And if C# has a garbage collector, which it does, then why are we ever worried about disposing resources?
Is IDisposable/Using/etc. a Skeet-approved concept? What does he think of it?
IDisposable is nothing special. It's just an interface that makes you have a Dispose() function. IDisposable won't clear anything or destroy objects. A call to Dispose() does nothing if that function does nothing.
The use of IDisposable is a pattern. It's so important that it gets its own language construct (the using block), but it's just a pattern.
The difference with a destructor, is that in .NET, the destructor is non-deterministic. You never know when the garbage collector will collect your object. You don't even know if it even will (unlike using delete in C++, which is deterministic).
So IDisposable is there for deterministically releasing unneeded references (and releasing unmanaged resources). The "disposed" object will remain in memory after you call Dispose until the garbage collector decides to collect it (at which point, the "destructor" will be called, unless you explicitly tell it not-to), if it ever decides to.
That's the main difference to using "destructors" (or finalizers, as they are called in C#).
As for the why do we need it:
Managed references to other objects prevent objects to be collected by the garbage collector. So you need to "release" those references (by, for example, setting the variables that reference those objects to null).
Objects in .NET can use unmanaged resources, if they use native libraries. For example, every control or bitmap in a Windows.Forms application uses a Win32 handler, which is unmanaged. If you don't release those resources, you may reach the handle limit in Windows if using any big application, easily. Also, if you need interoperability with any non-.NET API, you'll more likely have to allocate unmanaged memory (with the use of, for example, Marshal.AllocHGlobal), which will need to be released at some point: that point is generally the Dispose() function of the IDisposable, which must be called explicitly (or by using a using block).
As for the using block, it's more equivalent to:
var myObject = new MyDisposableClass();
try
{
...
}
finally {
myObject.Dispose();
}
So it does indeed save typing
Using a using block doesn't only call the .Dispose method; it calls the .Dispose method when you leave the block, however you leave it. So, if your code crashes, it will still call Dispose. The actual code would be closer to:
try
{
var obj = new SomeIDisposableObject;
// ...
}
catch (exception ex)
{
}
finally
{
obj.Dispose();
}
Additionally, destructors don't always fire when you expect them to. I've had a few bugs where the destructor is called after the program has apparently exited, and tried to access resources that no longer exist. Since you don't know when it will be called, it's difficult to fix this.
Writing memleak-free code in C++ isn't a problem for me, I just keep to the RAII idiom.
Writing memleak-free code in C# isn't very hard either, the garbage collector will handle it.
Unfortunately, writing C++/CLI code is a problem for me. I thought I had understood how it works, but I still have big problems and I hope you can give me some hints.
This is what I have:
A Windows service written in C# that uses C++ libraries (for example OpenCV) internally. The C++ classes are accessed with C++/CLI wrapper classes.
For example I have a MatW C++/CLI wrapper class for a cv::Mat image object, which takes as constructor argument a System::Drawing::Bitmap:
public ref class MatW
{
public:
MatW(System::Drawing::Bitmap ^bmpimg)
{
cv::Size imgsize(bmpimg->Width, bmpimg->Height);
nativeMat = new Mat(imgsize, CV_8UC3);
// code to copy data from Bitmap to Mat
// ...
}
~MatW()
{
delete nativeMat;
}
cv::Mat* ptr() { return nativeMat; }
private:
cv::Mat *nativeMat;
};
Another C++ class might be for example
class PeopleDetector
{
public:
void detect(const cv::Mat &img, std::vector<std::string> &people);
}
And its wrapper class:
public ref class PeopleDetectorW
{
public:
PeopleDetectorW() { nativePeopleDetector = new PeopleDetector(); }
~PeopleDetectorW() { delete nativePeopleDetector; }
System::Collections::Generic::List<System::String^>^ detect(MatW^ img)
{
std::vector<std::string> people;
nativePeopleDetector->detect(*img->ptr(), people);
System::Collections::Generic::List<System::String^>^ peopleList = gcnew System::Collections::Generic::List<System::String^>();
for (std::vector<std::string>::iterator it = people.begin(); it != people.end(); ++it)
{
System::String^ p = gcnew System::String(it->c_str());
peopleList->Add(p);
}
return peopleList;
}
And here is the call to the method in my Windows Service C# class:
Bitmap bmpimg = ...
using (MatW img = new MatW(bmpimg))
{
using (PeopleDetectorW peopleDetector = new PeopleDetector())
{
List<string> people = peopleDetector.detect(img);
}
}
Now, here's my questions:
is there anything wrong with my code?
do I have to use using in my C# code? It makes the code ugly, when there are multiple wrapper objects in use, because the using statements have to be nested
could I use Dispose() instead after having used the objects?
Could I just not bother and leave it to the garbage collector?
(no using, no Dispose())
is the above code the right way to return objects like List<string^>^ from C++/CLI to C#?
does using gcnew not mean that the garbage collector will take care of the objects and I don't have to care how and when to free them?
I know that's a lot of questions, but all I want is to get rid of my memory leak, so I listed everything that I think could possibly go wrong...
is there anything wrong with my code?
Not in what you've posted - you are applying using statements correctly. So your code sample is not the cause of your memory leaks.
do I have to use using in my C# code? It makes the code ugly, when there are multiple wrapper objects in use, because the using statements have to be nested
You don't have to, but you don't have to nest them syntactically. This is equivalent:
Bitmap bmpimg = ...
using (MatW img = new MatW(bmpimg))
using (PeopleDetectorW peopleDetector = new PeopleDetector())
{
List<string> people = peopleDetector.detect(img);
}
could I use Dispose() instead after having used the objects?
You could, but then you'll need a try/finally to ensure Dispose is always called, even when an exception is thrown. The using statement encapsulates that whole pattern.
Could I just not bother and leave it to the garbage collector? (no using, no Dispose())
C++ RAII is commonly applied to all kinds of temporary state clean-up, including things like decrementing a counter that was incremented in the constructor, etc. Whereas the GC runs in a background thread. It is not suitable for all the deterministic clean-up scenarios that RAII can take care of. The CLR equivalent of RAII is IDisposable, and the C# language interface to it is using. In C++, the language interface to it is (naturally) destructors (which become Dispose methods) and the delete operator (which becomes a call to Dispose). Ref class objects declared "on the stack" are really just equivalent to the C# using pattern.
is the above code the right way to return objects like List^ from C++/CLI to C#?
Pretty much!
does using gcnew not mean that the garbage collector will take care of the objects and I don't have to care how and when to free them?
You don't have to free the memory. But if the class implements IDisposable, then that is a totally separate issue from memory allocation. You have to call Dispose manually before you abandon the object.
Be wary of finalizers - these are a way of hooking into the GC to get your own clean-up code to run when the GC collects your objects. But they are not really fit for general use in application code. They run from a thread that you don't control, at a time you don't control, and in an order that you don't control. So if one object's finalizer tries to access another object with a finalizer, the second object may already have been finalized. There is no way to control the ordering of these events. Most of the original uses of finalizers are nowadays covered by SafeHandle.
You don't have a finalizer in the ref class.
In C++/CLI the destructors are called either when you create an instance of the class on the stack (C++ style) and then it goes out of scope, or you use the delete operator.
The finalizers are called by the GC when it's time to finalize the object.
In C# the GC handles the destruction of all the objects (there's no delete operator) so there's no distinction between the destructor and finalizer.
So the "destructors" with the ~ behave like c++ destructors, not at all like C# destructors.
The "destructors" in C++/CLI ref class are compiled into a .Net Dispose() method.
The equivilant to a C# destructor/finalizer is the finalizer method witch is defined with a ! (exclamation mark).
So, to avoid memory leaks, you need to define a finalizer:
!MatW()
{
delete nativeMat;
}
~MatW()
{
this->!MatW();
}
See the MSDN article Destructors and Finalizers in visual C++
Use the
I have a object and simply want to destroy it on some event. How to call the destructor in XNA?
Set the object to null and the Garbage Collector will pick it up on it's next run.
As a side note, if the object is something that you create often (enemies, bullets etc..), then you may want to use a pool instead of deleting the object. This would mean that object is recycled, and thus, the garbage collector is called less often which will increase performance.
While your mileage may vary, my preference is to use IDisposable and Dispose() of objects I no longer need. This is esp. true when you are using unmanaged resources, but having the Dispose() set up declares intent.
See this resource on GC.SuppressFinalize for a good example of how to implement IDisposable.
http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx
Set reference to this object to null.
After setting the object to null, if you want for some reason the object to be collected immediately, call GC.Collect().
What kind of object? If is an Disposable/IDisposable you should call object.Dispose()
Otherwise, you can just use object=null, and it will be 'cleaned' automatically. This is not C you're working in ;)
If your 'object' is actually a complex class or something with more objects in it, you might want to consider making it an IDisposable class.
If the object holds any unmanaged resources then implement IDisposable (and use using or call Dispose() on it when you're done with it).
If it doesn't hold unmanaged resources then the garbage collector will claim it "at some point" when there are no more references to it.
GC.Collect() will make the garbage collector collect and it will "destroy" your object if there are no references to it. This is not a very good idea since it has performance implications (it takes time and promotes other objects into a higher generation making them last longer in memory before being reclaimed).
Why do you need the object destroyed at a certain fixed time?
What you want to do is call GC.SuppressFinalize() if you are handling the cleanup yourself... Usually you use GC.SuppressFinalize() within an IDisposable class. See this code example for the common use of IDisposable:
http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx
If you really need to have it Garbage Collected right away:
var myObj = new MyObject();
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(myObj);
But I caution you that you should really let the object go out of scope, and let the GC collect the objects naturally. The .NET runtime is very efficient at managing memory as long as you don't try to do it's job.
EDIT
After reviewing the comments, I see you forgot to leave an important piece of information, in that you were binding the object in question to other objects methods. This means that the object that you are trying to finalize is not going to finalize until the method used to watch the event has finalized, thus keeping around a ton of extra objects in memory.
What you can do to break this strong reference is use an object called WeakReference. Or use lambdas to to break the strong references.
See this for an example of using a WeakReference
http://msdn.microsoft.com/en-us/library/system.weakreference.aspx
Or you can do something like this:
dym.cas += (x, y, z) => gameTime.ElapsedGameTime(x,y,z);
instead of
dym.cas += gameTime.ElapsedGameTime;
I am fascinated by the way the CLR and GC works (I'm working on expanding my knowledge on this by reading CLR via C#, Jon Skeet's books/posts, and more).
Anyway, what is the difference between saying:
MyClass myclass = new MyClass();
myclass = null;
Or, by making MyClass implement IDisposable and a destructor and calling Dispose()?
Also, if I have a code block with a using statement (eg below), if I step through the code and exit the using block, is the object disposed of then or when a garbage collection occurs? What would happen if I call Dispose() in the using block anyay?
using (MyDisposableObj mydispobj = new MyDisposableObj())
{
}
Stream classes (eg BinaryWriter) have a Finalize method? Why would I want to use that?
It's important to separate disposal from garbage collection. They are completely separate things, with one point in common which I'll come to in a minute.
Dispose, garbage collection and finalization
When you write a using statement, it's simply syntactic sugar for a try/finally block so that Dispose is called even if the code in the body of the using statement throws an exception. It doesn't mean that the object is garbage collected at the end of the block.
Disposal is about unmanaged resources (non-memory resources). These could be UI handles, network connections, file handles etc. These are limited resources, so you generally want to release them as soon as you can. You should implement IDisposable whenever your type "owns" an unmanaged resource, either directly (usually via an IntPtr) or indirectly (e.g. via a Stream, a SqlConnection etc).
Garbage collection itself is only about memory - with one little twist. The garbage collector is able to find objects which can no longer be referenced, and free them. It doesn't look for garbage all the time though - only when it detects that it needs to (e.g. if one "generation" of the heap runs out of memory).
The twist is finalization. The garbage collector keeps a list of objects which are no longer reachable, but which have a finalizer (written as ~Foo() in C#, somewhat confusingly - they're nothing like C++ destructors). It runs the finalizers on these objects, just in case they need to do extra cleanup before their memory is freed.
Finalizers are almost always used to clean up resources in the case where the user of the type has forgotten to dispose of it in an orderly manner. So if you open a FileStream but forget to call Dispose or Close, the finalizer will eventually release the underlying file handle for you. In a well-written program, finalizers should almost never fire in my opinion.
Setting a variable to null
One small point on setting a variable to null - this is almost never required for the sake of garbage collection. You might sometimes want to do it if it's a member variable, although in my experience it's rare for "part" of an object to no longer be needed. When it's a local variable, the JIT is usually smart enough (in release mode) to know when you're not going to use a reference again. For example:
StringBuilder sb = new StringBuilder();
sb.Append("Foo");
string x = sb.ToString();
// The string and StringBuilder are already eligible
// for garbage collection here!
int y = 10;
DoSomething(y);
// These aren't helping at all!
x = null;
sb = null;
// Assume that x and sb aren't used here
The one time where it may be worth setting a local variable to null is when you're in a loop, and some branches of the loop need to use the variable but you know you've reached a point at which you don't. For example:
SomeObject foo = new SomeObject();
for (int i=0; i < 100000; i++)
{
if (i == 5)
{
foo.DoSomething();
// We're not going to need it again, but the JIT
// wouldn't spot that
foo = null;
}
else
{
// Some other code
}
}
Implementing IDisposable/finalizers
So, should your own types implement finalizers? Almost certainly not. If you only indirectly hold unmanaged resources (e.g. you've got a FileStream as a member variable) then adding your own finalizer won't help: the stream will almost certainly be eligible for garbage collection when your object is, so you can just rely on FileStream having a finalizer (if necessary - it may refer to something else, etc). If you want to hold an unmanaged resource "nearly" directly, SafeHandle is your friend - it takes a bit of time to get going with, but it means you'll almost never need to write a finalizer again. You should usually only need a finalizer if you have a really direct handle on a resource (an IntPtr) and you should look to move to SafeHandle as soon as you can. (There are two links there - read both, ideally.)
Joe Duffy has a very long set of guidelines around finalizers and IDisposable (co-written with lots of smart folk) which are worth reading. It's worth being aware that if you seal your classes, it makes life a lot easier: the pattern of overriding Dispose to call a new virtual Dispose(bool) method etc is only relevant when your class is designed for inheritance.
This has been a bit of a ramble, but please ask for clarification where you'd like some :)
When you dispose an object, the resources are freed. When you assign null to a variable, you're just changing a reference.
myclass = null;
After you execute this, the object myclass was referring to still exists, and will continue to until the GC gets around to cleaning it up. If Dispose is explicitly called, or it's in a using block, any resources will be freed as soon as possible.
The two operations don't have much to do with each others.
When you set a reference to null, it simply does that. It doesn't in itself affect the class that was referenced at all.
Your variable simply no longer points to the object it used to, but the object itself is unchanged.
When you call Dispose(), it's a method call on the object itself. Whatever the Dispose method does, is now done on the object. But this doesn't affect your reference to the object.
The only area of overlap is that when there are no more references to an object, it will eventually get garbage collected. And if the class implements the IDisposable interface, then Dispose() will be called on the object before it gets garbage collected.
But that won't happen immediately after you set your reference to null, for two reasons.
First, other references may exist, so it won't get garbage collected at all yet, and second, even if that was the last reference, so it is now ready to be garbage collected, nothing will happen until the garbage collector decides to delete the object.
Calling Dispose() on an object doesn't "kill" the object in any way. It is commonly used to clean up so that the object can be safely deleted afterwards, but ultimately, there is nothing magical about Dispose, it's just a class method.