3

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?

smartcaveman
  • 41,281
  • 29
  • 127
  • 212
  • 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 Mar 17 '11 at 13:50

4 Answers4

3

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.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
2

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.

Jon
  • 428,835
  • 81
  • 738
  • 806
  • Is there a test to determine if something is an unmanaged resource, or do you just have to know what all of the possible options are? – smartcaveman Mar 17 '11 at 13:53
  • @smartcaveman: No, but there are good rules of thumb: if you see `IntPtr`, it's an unmanaged resource; if you get something using P/Invoke, it's an unmanaged resource; if you see `unsafe` pointers used, it might be unmanaged memory (although this is rare). – Jon Mar 17 '11 at 14:07
0

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.

Chris Haas
  • 53,986
  • 12
  • 141
  • 274
  • 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. – supercat Mar 17 '11 at 15:12
  • Unmanaged resources are things the garbage-collector doesn't know how to clean up, and which can cause trouble if not cleaned up. The garbage-collector doesn't know how to clean up abandoned objects' subscriptions to events from long-lived objects, and such subscriptions can wreak unbounded havoc. A "managed resource" is an object which has cleanup responsibilities, but can handle them in a finalizer. If such an object is abandoned, it will usually get cleaned up eventually. If the garbage-collector is assumed to run at least occasionally... – supercat Mar 17 '11 at 22:33
  • ...the amount of uncleaned mess from abandoned managed resources that can accumulate will be limited by the amount of work that can be done before those objects get finalized. By contrast, even if the mess from some type of abandoned unmanaged resource might get cleaned up eventually, there may be nothing to prevent the mess from accumulating so much as to strangle the system before that happens. If a collection object that would live for a week is enumerated once every second by an enumerator that attaches a CollectionChanged event, but the enumerators are abandoned rather than Disposed... – supercat Mar 17 '11 at 22:42
  • ...then unless the enumerator uses some tricky means of cleaning events in its Finalize() routine (note that the code for this is *VERY* tricky!) the CollectionChanged object will build up more than 600,000 subscribers--a tally which could bring the system to its knees (remember that adding each subscriber will mean creating a new subscription list--by the time there are 10,000 subscribers that list is going to be on the Large Object Heap). – supercat Mar 17 '11 at 22:46
0

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.

supercat
  • 77,689
  • 9
  • 166
  • 211
  • I don't agree with your definition of unmanaged, especially your sample with event handlers. They are not unmanaged resources. – Daniel Hilgarth Mar 17 '11 at 15:17
  • What happens if an object subscribes to an event from a long-lived object but is abandoned without unsubscribing? If many such objects are created and abandoned during the lifetime of a long-lived object, is there any limit to the amount of memory that can be uselessly tied up? Regarding an event handler from a long-lived object as anything other than an unmanaged resource that absolutely *REQUIRES* cleanup is a recipe for memory leaks. – supercat Mar 17 '11 at 15:20
  • Your definition of unmanaged is: "It generates a memory leak, if you don't clean it up, when you are done". That's my problem with your answer. In your definition a list of objects in a long living object is also an unmanaged resource, if the long living object has no internal clean up routine. – Daniel Hilgarth Mar 17 '11 at 15:23
  • @Daniel Hilgarth: It is useful to have a term to describe any and all entities requiring cleanup that won't be performed by the CLR. Under what circumstances is it useful to have a term which refers to entities in the world of unmanaged code that require cleanup, but excludes those that exist in the world of managed code, but which nonetheless require cleanup *that the CLR can't perform*? – supercat Mar 17 '11 at 15:29
  • @Daniel Hilgarth: My definition of "unamanged" is essentially "It causes problems if you don't clean up after you're done". I do not consider a reasonably-bounded waste of memory to be a problem, but an unbounded waste is a problem. Suppose an IEnumerator attaches itself to a collection's event hander but is never unsubscribed. Is there any limit to how many times a collection may be enumerated during its useful lifetime? Is there any limit to how much memory will be wasted by all the subsribed-but-abandoned objects? – supercat Mar 17 '11 at 15:33
  • I agree, that a term is useful, but the term you are using ("unmanaged resource") is already defined with a different meaning. The CLR can't clean up the objects that subscribed to the event in your long living object, because there is still a reference to those objects. What I am saying: Your use of the term "unmanaged resource" differs to the widely used definition. – Daniel Hilgarth Mar 17 '11 at 15:35
  • @Daniel Hilgarth: If an object adds itself to a list of objects in a long-lived object and never removes itself, nothing else can be expected to remove it, its presence on the list may become useless, and there's nothing that would prevent the number of objects sitting uselessly on that list from growing to the point of choking the system, I would regard that as an unmanaged resource. The object manipulates a longer-lived entity (the list) in a way which could wreak havoc if not cleaned up. – supercat Mar 17 '11 at 15:37
  • As I am saying: It's not an "unmanaged resource". It's simply a memory leak. There is your term ;-) – Daniel Hilgarth Mar 17 '11 at 15:38
  • @Daniel Hilgarth: Microsoft initially defined the term by example; I'll agree that common usage has come to regard the term rather more narrowly than is useful. In simplest terms, Microsoft defined the term by giving examples of a variety of objects that happen to share two characteristics; many people observed that the objects all shared one characteristic, and have come to regard the term as applying to that characteristic, even though another shared characteristic is much more important. – supercat Mar 17 '11 at 15:42
  • Do you have any links to that? – Daniel Hilgarth Mar 17 '11 at 15:46
  • @Daniel Hilgarth: Outside of arguments about what a "managed resource" is, is there anything that can be said of "unamanged resources" which would could not be said of "entities which require manual cleanup and which, if not cleaned up manually, may cause problems"? If everything that can be said of the former can be said of the latter, why restrict the definition of the former? – supercat Mar 17 '11 at 15:52
  • @Daniel Hilgarth: A typical definition from http://msdn.microsoft.com/en-us/library/ms177197.aspx: "However, a type may use resources that the garbage collector does not know how to release. These resources are known as unmanaged resources (native file handles, for example)." Note that the garbage-collector *does not know how to clean up event subscriptions* held by long-lived objects on behalf of abandoned objects, since it can't tell that the objects in question are abandoned. – supercat Mar 17 '11 at 17:05