What Is Meant by "Managed" VS "Unmanaged" Resources in .Net

What is meant by managed vs unmanaged resources in .NET?

The term "unmanaged resource" is usually used to describe something not directly under the control of the garbage collector. For example, if you open a connection to a database server this will use resources on the server (for maintaining the connection) and possibly other non-.net resources on the client machine, if the provider isn't written entirely in managed code.

This is why, for something like a database connection, it's recommended you write your code thusly:

using (var connection = new SqlConnection("connection_string_here"))
{
// Code to use connection here
}

As this ensures that .Dispose() is called on the connection object, ensuring that any unmanaged resources are cleaned up.

Determine managed vs unmanaged resources

A FileStream must use unmanaged resources, but when I implement the IDisposable pattern, should I consider this a managed or unmanaged resources?

A FileStream is a managed resource.

Managed resources are classes that contain (and must manage) unmanaged resources. Usually the actual resource is several layers down.

I've been assuming thus far that if the object implements IDisposable, then it is managed.

Correct.

How would I know that IntPtr should be handled as an unmanaged resoruce?

From the documentation of the API that you got its value from. But do note that in practice, most programmers never deal with unmanaged resources directly. And when you do have to, use the SafeHandle class to turn an unmanaged resource into a managed resource.

Managed vs Unmanaged Resources in .NET. What's the difference?

You got it right:

Managed resources are managed by the CLR, unmanaged aren't. In other words: Managed resources live only in the .NET world where as unmanaged resources are from the normal Win32 world.

What exactly are unmanaged resources?

Managed resources basically means "managed memory" that is managed by the garbage collector. When you no longer have any references to a managed object (which uses managed memory), the garbage collector will (eventually) release that memory for you.

Unmanaged resources are then everything that the garbage collector does not know about. For example:

  • Open files
  • Open network connections
  • Unmanaged memory
  • In XNA: vertex buffers, index buffers, textures, etc.

Normally you want to release those unmanaged resources before you lose all the references you have to the object managing them. You do this by calling Dispose on that object, or (in C#) using the using statement which will handle calling Dispose for you.

If you neglect to Dispose of your unmanaged resources correctly, the garbage collector will eventually handle it for you when the object containing that resource is garbage collected (this is "finalization"). But because the garbage collector doesn't know about the unmanaged resources, it can't tell how badly it needs to release them - so it's possible for your program to perform poorly or run out of resources entirely.

If you implement a class yourself that handles unmanaged resources, it is up to you to implement Dispose and Finalize correctly.

What are managed resources and unmanaged resources?

Managed resources are those that are fully written in .NET. Though not normally subject to classic memory leaks, one can still leak memory by not dereferencing unused resources (the most common reason is to not un-register event handlers).

Unmanaged resources are those that are generally those that are not pure .NET (and in the same process) - examples are:

  • COM components
  • Database connections/transactions
  • Window handles
  • Filesystem handles
  • Registry handles
  • Network connections
  • etc... etc...

For these, you need to implement the Dispose pattern, correctly and ensure proper disposal when you have finished using them.

Do we really need to worry about memory leaks or not?

Yes, we do need to worry about them, in particular when going outside of .NET.

How do we distinguish between managed and unmanaged resources in C#? Is TextFieldParser unmanaged?

You're missing the point. Whenever any class implements IDisposable, you should call Dispose when you're done with it.

Whether the class uses unmanaged resources or not is internal to the class, you shouldn't care about it at all. Every class that uses unmanaged resources should also have a finalizer that clears up those unmanaged resources if you didn't dispose of the class explicitly. Dispose just allows you to clean its resources (both managed and unmanaged, though this doesn't necessarily mean freeing up the memory immediately) in a more deterministic and immediate fashion. For example, Disposeing a FileStream will release the file handle immediately, while if you don't Dispose (or Close), the file will be opened until the next collection and finalization.

EDIT:

To show that Dispose may also be necessary to clean up managed resources, we only have to look at event handlers. In particular, the case when you're subscribing on an event of a class that has a longer lifetime than you do:

var control = new MyHelperControl();
MyParentForm.Click += control.DoSomething();

Now, even if control goes out of scope, it will survive as long as MyParentForm - it's still referenced by the event handler. The same problem grows to absurd proportions when the parent has the same lifetime as the whole application - that's can be a huge memory leak. An example would be registering event handlers on the main form of an application, or on a static event.

There might also be other things that happen in the Dispose. For example, again with Windows forms, when you call Dispose on a Control, a whole lot of things happen:

  • All the unmanaged resources are released. Since Winforms controls are wrappers of the native controls to an extent, this is usually a lot of resources - the control itself, any pens, brushes, images... all of those are native resources. They will also be released if you forget a Dispose, since they all have finalizers, but it might take more time - which is especially painful when you create and destroy a lot of those objects. For example, there's a limited supply of GDI+ object handles, and if you run out, you get OutOfMemoryException and you're out.
  • Dispose of all sub-controls.
  • Remove any context menu handlers (remember, context menu is a separate component that's only linked to another control).
  • Remove any data bindings.
  • Remove itself from the parent container, if any.
  • If the control is a window with its own message loop, kill the message loop.

The funny part is that the unmanaged resources matter the least, really - they always have a finalizer. The managed resources are trickier, because you're more or less forbidden to handle managed references in a finalizer (because they might have already been released, or they might be in the middle of being released, or they might start being released in the middle of your finalizer... it's complicated). So doing MyParentForm.Click -= this.OnClick; is not a good thing to have in your finalizer - not to mention that it would require you to make every such class finalizable, which isn't exactly free, especially when you expect the finalizer to actually run (when you do a Dispose, the GC is alerted that this instance no longer needs a finalization).

What is the difference between managed and native resources when disposing? (.NET)

A managed resource is another managed type, which implements IDisposable. You need to call Dispose() on any other IDisposable type you use. Native resources are anything outside the managed world such as native Windows handles etc.


EDIT: Answer to question in comment (too long for comment)

No that is just a managed type. A correctly constructed type, which doesn’t implement IDisposable will be handled by the garbage collector and you don’t have to do anything else. If your type uses a native resource directly (e.g. by calling Win32 libraries), you must implement IDisposable on your type and dispose of the resource(s) in the Dispose method. If your type uses a native resource encapsulated by another type which implements IDisposable, you must call Dispose() on instances of this type in the Dispose method of your type.



Related Topics



Leave a reply



Submit