3
votes

I was reading Wrox's Professional C# 4 and .NET 4 chapter on "Memory Management and Pointers", specifically about how Garbage Collection works in .NET. It said the reason that "the garbage collector does not know how to free unmanaged resources (such as file handles, network connections, and database connections)", which is why such classes should either declare a destructor (aka "finalizer") or implement IDisposable.

It seems like all these examples of "unmanaged resources" are related to interaction with a system that is extrinsic from the application and independent of the .NET Framework. However, I'm not sure if that is the complete distinction that is being made, so,

What exactly is the distinctive characteristic that an unmanaged resource has and a managed resource doesn't have?

4
Unmanaged code gives developers the option of pointers, direct control of hardware and is known for faster execution though all resource management has to be done by the devs.Aravind

4 Answers

3
votes

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.

2
votes

With managed resources (i.e., memory) you don't have to worry about what happens to them after you are done using them; the CLR takes care of that.

Unmanaged resources (there are several types of these: Windows kernel objects, GDI objects, USER objects) have to be released back to the system when you are done using them. This happens automatically when your process terminates, but if it leaks them in the meantime you have a big problem because you are leaking resources shared among all processes in the system.

Of course, there are several classes in .NET that wrap these unmanaged resources (using the dispose/finalize pattern) and do the hard work for you. Use those if you can.

0
votes

The term "unmanaged resource" is confusing. A more useful concept is "cleanup responsibility". If an object holds unmanaged resources, that means three things:

  1. It manipulates some longer-lived entity outside itself,
  2. That entity may be in a state requiring cleanup, and
  3. The object is responsible for providing the required cleanup

Generally, the term "managed resource" is used to refer to objects which hold unmanaged resources, but which will receive notification from the garbage collector (via the Finalize routine) if they are found to be abandoned, and which will use such notification to provide cleanup (in case they got abandoned before their normal cleanup method was invoked). Some people use the term "managed resource" to refer to things that don't require any cleanup, but I don't like such usage, since there isn't any other good term to refer to things that should be cleaned up manually but will use finalization as a fallback in case normal cleanup doesn't happen.

Note that while unmanaged resources are often things like OS handles for files, GDI entities, etc. it's a mistake to think of them in such terms. It's possible to have unmanaged resources which do not access anything outside the .Net framework; event handlers are a common example of that. The critical aspect of unmanaged resources is that they need cleanup, and failure to perform such cleanup will have some undesirable consequence.

0
votes

I would say that generally anything created using the .Net framework is a managed resource. Internally they might use unmanaged resources but from your perspective they are managed. One of the exceptions to this is when you P/Invoke. Although you create a function that works with .Net, the call gets passed outside of the .Net "sandbox" and therefor is considered unmanaged.

Response to @supercat

Events from long-lived objects may be handled entirely within the .net framework, but they definitely need to be regarded as unmanaged resources to prevent memory leaks

I think there's two separate things here. There's the discussion of managed vs unmanaged and there's the discussion of memory management for an application. You probably should treat some objects as if they were unmanaged but that doesn't mean that they are unmanaged. For instance, the Brush class I would consider managed but you should treat it as unmanaged by calling Dispose(). Hidden/abstracted within the class are unmanaged objects that you hope Dispose() takes care of. But Dispose() doesn't actually free any resourced, its just a pattern that you hope developers implement correctly.

To go further I would say that most unmanaged objects are created by calling a CreateXYZ() Win32 method that returns a pointer but need to be released using a `DestroyXYZ()/DeleteXYZ()' method that takes the same pointer. Managed objects on the other hand implement Dispose/Finalize to do this for you. Once again, you hope that the writers of managed resources have done this but there's no guarantee.