What I am trying to understand is when I am creating my own classes, how do I know what is a managed vs unmanaged resource so I know if my class needs to provide the ability to clean it up or if GC will eventually do it. Also, going a little deeper, when I create a .Dispose() method there will be a block for managed resources and a block for unmanaged resources and how do I know which resources should get cleaned up in which block.
I have read many answers about managed vs unmanaged resources in a C# program but most of them are providing the definition with regards to GC cleanup as in "managed resource are cleaned up by GC and unmanaged resources are not". That doesn't help me because I can't see how GC determines what it will clean up and what it will leave behind. I also understand that if a class provides a .Dispose() method that my program should execute it.
I have seen answers stating that if I use a WIN32 API, I've created an unmanaged resource. If I don't call a WIN32 API, does that mean I don't have any unmanaged resources? I've also stumbled over Marshall. Does Marshall also create unmanaged resources? Are there other "keywords / classes" to use to identify that I'm creating unmanaged resources?
Please exclude from your answers anything about "managed resources that are tying up huge amounts of memory". I understand that it would be nice to give the ability to free up this memory but it is not a requirement as the GC will eventually do it, just not always in a timely manner.
Usually if you are not crossing the boundaries of native and managed codes you don't have to bother about releasing unmanaged resources in your classes.
When you are running your .NET application, the framework allocates a managed slice in the memory for it, where almost everything that you can access from the .NET framework will be stored and tracked by the GC. Everything else falls outside of this slice, left without the sharp eye of the GC.
So for your question about how the GC determines which resources should be collected and which not, the short answer is that it doesn't know anything about unmanaged resources, so it also does not able to collect them.
These worlds - the native and the managed - are separated but they can communicate with eachother and thats what Marshalling is for. You can read more about it here. With that of course you can create unmanaged resources but that does not mean that you will do every time when you are using it.
It's also a bit extreme to say that every time you are using Win32 APIs you will create native resources that you must release.
When you use Platform Invoke or C++/CLI wrapper calls on any native code which creates pointers or anything which should be released by hand in the native world (those of course are not tracked by the GC), you have to release them manually if they are not released already by the native side. But if you use APIs that just works with primitive types then you don't have to release anything.
If you are not using anything from above then there is a good chance that you don't have to prepare your classes for directly release anything unmanaged.
There are types using native resources - you probably already came accross - which are managed wrappers under the hood. They release those resources in their Dispose implementation with marshalling.
For example the FileStream managed class is holding an unmanaged handle to the given file. The FileStream itself is a managed class tracked and collected by the GC, but the unmanaged handle is not, it must be released manually, so if you, the user of the FileStream are not calling its Dispose method in your code, that handle will remain in the memory leaking until the application exits.
I want to know about unmanaged resources.
Can anyone please give me a basic idea?
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.
Some users rank open files, db connections, allocated memory, bitmaps, file streams etc. among managed resources, others among unmanaged. So are they managed or unmanaged?
My opinion is, that the response is more complex: When you open file in .NET, you probably use some built-in .NET class System.IO.File, FileStream or something else. Because it is a normal .NET class, it is managed. But it is a wrapper, which inside does the "dirty work" (communicates with the operating system using Win32 dlls, calling low level functions or even assembler instructions) which really open the file. And this is, what .NET doesn't know about, unmanaged.
But you perhaps can open the file by yourself using assembler instructions and bypass .NET file functions. Then the handle and the open file are unmanaged resources.
The same with the DB: If you use some DB assembly, you have classes like DbConnection etc., they are known to .NET and managed. But they wrap the "dirty work", which is unmanaged (allocate memory on server, establish connection with it, ...).
If you don't use this wrapper class and open some network socket by yourself and communicate with your own strange database using some commands, it is unmanaged.
These wrapper classes (File, DbConnection etc.) are managed, but they inside use unmanaged resources the same way like you, if you don't use the wrappers and do the "dirty work" by yourself. And therefore these wrappers DO implement Dispose/Finalize patterns. It is their responsibility to allow programmer to release unmanaged resources when the wrapper is not needed anymore, and to release them when the wrapper is garbage collected. The wrapper will be correctly garbage collected by garbage collector, but the unmanaged resources inside will be collected by using the Dispose/Finalize pattern.
If you don't use built-in .NET or 3rd party wrapper classes and open files by some assembler instructions etc. in your class, these open files are unmanaged and you MUST implement dispose/finalise pattern. If you don't, there will be memory leak, forever locked resource etc. even when you don't use it anymore (file operation complete) or even after you application terminates.
But your responsibility is also when using these wrappers. For those, which implement dispose/finalise (you recognize them, that they implement IDisposable), implement also your dispose/finalise pattern and Dispose even these wrappers or give them signal to release their unmanaged resources. If you don't, the resources will be after some indefinite time released, but it is clean to release it immediately (close the file immediately and not leaving it open and blocked for random several minutes/hours). So in your class's Dispose method you call Dispose methods of all your used wrappers.
Unmanaged resources are those that run outside the .NET runtime (CLR)(aka non-.NET code.) For example, a call to a DLL in the Win32 API, or a call to a .dll written in C++.
An "unmanaged resource" is not a thing, but a responsibility. If an object owns an unmanaged resource, that means that (1) some entity outside it has been manipulated in a way that may cause problems if not cleaned up, and (2) the object has the information necessary to perform such cleanup and is responsible for doing it.
Although many types of unmanaged resources are very strongly associated with various type of operating-system entities (files, GDI handles, allocated memory blocks, etc.) there is no single type of entity which is shared by all of them other than the responsibility of cleanup. Typically, if an object either has a responsibility to perform cleanup, it will have a Dispose method which instructs it to carry out all cleanup for which it is responsible.
In some cases, objects will make allowances for the possibility that they might be abandoned without anyone having called Dispose first. The GC allows objects to request notification that they've been abandoned (by calling a routine called Finalize), and objects may use this notification to perform cleanup themselves.
Terms like "managed resource" and "unmanaged resource" are, unfortunately, used by different people to mean different things; frankly think it's more useful to think in terms of objects as either not having any cleanup responsibility, having cleanup responsibility that will only be taken care of if Dispose is called, or having cleanup responsibility which should be taken care of via Dispose, but which can also be taken care of by Finalize.
The basic difference between a managed and unmanaged resource is that the
garbage collector knows about all managed resources, at some point in time
the GC will come along and clean up all the memory and resources associated
with a managed object. The GC does not know about unmanaged resources, such
as files, stream and handles, so if you do not clean them up explicitly in
your code then you will end up with memory leaks and locked resources.
Stolen from here, feel free to read the entire post.
Any resource for which memory is allocated in the .NET managed heap is a Managed resource. CLR is completly aware of this sort of memory and will do everything to make sure that it doesn't go orphaned. Anything else is unmanaged. For example interoping with COM, might create objects in the proces memory space, but CLR will not take care of it. In this case the managed object that makes calls across the managed boundry should own the responsibility for anything beyond it.
Let us first understand how VB6 or C++ programs (Non Dotnet applications) used to execute.
We know that computers only understand machine level code. Machine level code is also called as native or binary code. So, when we execute a VB6 or C++ program, the respective language compiler, compiles the respective language source code into native code, which can then be understood by the underlying operating system and hardware.
Native code (Unmanaged Code) is specific (native) to the operating system on which it is generated. If you take this compiled native code and try to run on another operating system it will fail. So the problem with this style of program execution is that, it is not portable from one platform to another platform.
Let us now understand, how a .Net program executes. Using dotnet we can create different types of applications. A few of the common types of .NET applications include Web, Windows, Console and Mobile Applications. Irrespective of the type of the application, when you execute any .NET application the following happens
The .NET application gets compiled into Intermediate language (IL). IL is also referred as Common Intermediate language (CIL) and Microsoft Intermediate language (MSIL). Both .NET and non .NET applications generate an assembly. Assemblies have an extension of .DLL or .EXE. For example if you compile a windows or Console application, you get a .EXE, where as when we compile a web or Class library project we get a .DLL. The difference between a .NET and NON .NET assembly is that, DOTNET Assembly is in intermediate language format where as NON DOTNET assembly is in native code format.
NON DOTNET applications can run directly on top of the operating system, where as DOTNET applications run on top of a virtual environment called as Common Language Runtime (CLR). CLR contains a component called Just In-Time Compiler (JIT), which will convert the Intermediate language into native code which the underlying operating system can understand.
So, in .NET the application execution consists of 2 steps
1. Language compiler, compiles the Source Code into Intermediate Language (IL)
2. JIT compiler in CLR converts, the IL into native code which can then be run on the underlying operating system.
Since, a .NET assembly is in Intermedaite Language format and not native code, .NET assemblies are portable to any platform, as long as the target platform has the Common Language Runtime (CLR). The target platform's CLR converts the Intermedaite Language into native code that the underlying operating system can understand. Intermediate Languge is also called as managed code. This is because CLR manages the code that runs inside it. For example, in a VB6 program, the developer is responsible for de-allocating the memory consumed by an object. If a programmer forgets to de-allocate memory, we may run into hard to detecct out of memory exceptions. On the other hand a .NET programmer need not worry about de-allocating the memory consumed by an object. Automatic memory management, also known as grabage collection is provided by CLR. Apart, from garbage collection, there are several other benefits provided by the CLR, which we will discuss in a later session. Since, CLR is managing and executing the Intermediate Language, it (IL) is also called as managed code.
.NET supports different programming languages like C#, VB, J#, and C++. C#, VB, and J# can only generate managed code (IL), where as C++ can generate both managed code (IL) and un-managed code (Native code).
The native code is not stored permanently anywhere, after we close the program the native code is thrown awaya. When we execute the program again, the native code gets generated again.
.NET program is similar to java program execution. In java we have byte codes and JVM (Java Virtual Machine), where as in .NET we Intermediate Language and CLR (Common Language Runtime)
This is provided from this link - He is a great tutor.
http://csharp-video-tutorials.blogspot.in/2012/07/net-program-execution-part-1.html
Unmanaged and managed resources are based on application domain.
From my understanding, unmanaged resource is everything that is used to make connection to outside of your application domain.
It could be HttpClient class that you resort to fetch data outside of your domain or a FileStream that helps you to read/write from/to a file.
we use Using block to dispose these kind of classes objects immediately after our work is done because GC in the first place care about inside the process resources not outside ones, although it will be disposed by the GC at the end.
I have a c# class. Whenever this class is not in use anymore I want to do some things. For example log the current state and so on.
I want to be sure that this method is run everytime when the class is not used anymore.
I don't want just use a simple method because I can't be sure that every user is calling it.
I have no resources (like file handles) to clear up.
Is the best way to use a destructor?
"not in use" is when (for example):
a user uses my class in a form and the form is closed
the class is used in an application and this application is shut down
It depends. C# .NET utilizes a garbage collector that implicitly cleans up objects for you. Normally, you cannot control the clean up of objects - the garbage collector does that. You can implement a destructor in your class if you desire, but you may get a performance hit. MSDN has this to say on destructors:
In general, C# does not require as much memory management as is needed
when you develop with a language that does not target a runtime with
garbage collection. This is because the .NET Framework garbage
collector implicitly manages the allocation and release of memory for
your objects. However, when your application encapsulates unmanaged
resources such as windows, files, and network connections, you should
use destructors to free those resources. When the object is eligible
for destruction, the garbage collector runs the Finalize method of the
object.
and finally on performance:
When a class contains a destructor, an entry is created in the
Finalize queue. When the destructor is called, the garbage collector
is invoked to process the queue. If the destructor is empty, this just
causes a needless loss of performance.
There are other ways to manage resources besides a destructor:
Cleaning Up Unmanaged Resources
Implementing a Dispose Method
using Statement (C# Reference)
No that would not be the best way, a destructor is costly.
The best way would be to add a Close() or maybe the Dispose() (IDiposable interface) method.
But you need to define very carefully what "not in use anymore" means, and if you want the extra trouble to manage and track that.
You can use a destructor to automate it, but it would be better to make that conditional (Debug config only). Also consider that the destuctor implements "non deterministic" finalization.
If you want something to run when it's done, you should implement IDisposable.
DOT NET garbage collector can only deals with memory resources or it also handles other resources used by orphaned object?
How CLR deals to free these other resources used by orphaned object.
The GC only deals with managed objects.
All unmanaged resources need to be dealt with manually:
Implement the IDisposable interface on any types that use unmanaged resources.
Ensure that you call the Dispose method when you're done with using any objects that implement IDisposable. This is often done by using a using block.
The .Net GC manages only objects that are put up on managed heap, i.e. managed objects. These managed objects may inturn access unmanaged objects like DB connection or a file handle etc. The developer needs to free these resources by implementing IDisposable or Finalize, depending on your needs.
MSDN states that:
A type must implement Finalize when it
uses unmanaged resources such as file
handles or database connections that
must be released when the managed
object that uses them is reclaimed.
See the IDisposable interface for a
complementary and more controllable
means of disposing resources.
Here's the link for the same: http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx
What is the difference between C++ memory management and .NET memory management ?
In C++, you can either allocate objects with static storage so they are around for the whole program, allocate them on the stack when they are local to a function (in which case they are destroyed when the containing block exits), or allocate them on the heap (in which case they are only destroyed when you say so by explicitly calling the appropriate de-allocation function). Heap memory is allocated as raw memory with malloc and released with free, or allocated and constructed into an object with new, and then the object destroyed and the memory released with delete.
C# provides an illusion of infinite memory --- you cannot free memory explicitly, only allocate memory and construct an object with new. Instead the GC reclaims the memory for objects you can no longer access so that it can be reused for new objects.
In C++, class destructors are run when an object is destroyed. This gives each object a chance to release any associated resources whether they are more objects, or external resources such as file handles or database handles.
In C#, you must explicitly manage the release of non-memory resources by calling a release function. The using facility allows you to get the compiler to call Dispose() automatically for you, but this is still separate from the object lifetime --- the memory for the object is reclaimed when the GC system decides to (which may be never).
In C++, facilities like std::shared_ptr (or boost::shared_ptr with older compilers) allow you to pass the responsibility of destroying heap objects over to the C++ runtime by reference-counting the objects. When the last instance of shared_ptr that references a given object is destroyed, then the referenced object is destroyed too and its memory reclaimed. This avoids many of the pitfalls associated with manual memory management.
In .NET, memory is treated different than all other resources: While you have to take care of releasing all resources you need, you don't have to worry about memory.
In C++, you have to take care to release all resources you use, including dynamically allocated memory. However, C++ employs a number of tools and techniques (namely automatic scope-based allocation/deallocation and RAII) to help you with this. In a decade of writing C++ code, I have rarely ever (read: on average less than once per year) manually freed memory and if so, it was in a RAII handle class.
In C#, there is a whole lot less to worry about.
When you want to work with an object in C#, you can simply create it; and once you're done with it, you don't have to do anything else. A background worker (the Garbage Collector) will clean it up behind the scenes when it realises you're not using it any more.
In vanilla C++, there aren't any background processes running to clean up memory. This means that, any time you manually allocate memory (which is a lot of the time), you are responsible for deleting it once you're finished using it. Care must also be taken to ensure you don't delete the same thing twice.
A note on the C# side of things: This doesn't mean you can completely ignore how memory works. It's very helpful to know what happens behind the scenes. In general, though, you won't have to worry about it much.
Edit: As GMan notes below (if I'm understanding him correctly), you can deal with memory management in C++ by letting every allocation be scoped, and thus the C++ environment will look after allocation and deletion for you. In that sense, you again have to understand how C++ allocates and deletes in order to not run into troubles.
some c++ open source choosed to create their own memory gabrage collector like V8 javascript engine to avoid all problems of memory leaks.