HeapAlloc, HeapCreate Is garbage-collectable in C# - c#

I have created a memory allocation library that can't be collected by GC. (https://github.com/10sa/Unmanaged-Memory)
The heap area allocated by this library is basically obtained by using the WinAPI GetProcessHeap() function. You can also create a heap area and assign it to it. However, the function used to create the heap area is the HeapCreate function.
Question is,
1. Is this memory area (GetProcessHeap()) managed by GC?
2. If you create a new heap area using the HeapCreate function, can the generated heap area be collected by the GC?
3. If all of the above questions are true, How can I create a memory region in C # that is not collected without using Global Heap?

no; the clue is in the name ("unmanaged memory"), and in the fact that it is being allocated by the OS, not the CLR
no!
n/a
What are you trying to do here? There are already extensive inbuilt mechanisms for allocating unmanaged memory through the CLR without needing an external tool.
Additionally, in the examples: allocating 4 bytes in unmanaged memory is terribly terribly expensive and unnecessary. Usually when we talk about unmanaged memory we're talking about slabs of memory - huge chunks that we then sub-divide and partition internally via clever code.

In Win32/Win64 and C/C++ the Heap API were a godsend, allowing any amount of temporary allocation, with all allocations from the custom heap being freed in a single call. They are likely unnecessary in .NET.
Allow me some skepticism for Microsoft's advice on good practices. I remember a division meeting where we were told that memory leaks are an inescapable fact of life.

Related

Memory allocation/deallocation when working with C# and C++ unmanaged

I am working with some C# and C++ unmanaged code and there are two things I don't understand when dealing with memory. If someone can help me understand:
If a variable is dynamically allocated under C# (using new) and then is passed to the C++ unmanaged code. Does that variable memory needs to be deallocated manually under the C++ unmanaged code by the user ?
If a variable is dynamically allocated under C++ unmanaged (using new) and then passed to C#, is it safe to say the Garbage Collector will deallocate that memory ?
No, since the object is allocated on managed heap GC will handle deallocation as usual. The problem is you must tell him not to deallocate or change address of the object while it is used from unmanaged code because GC can't know how long you are going to use the object from the unmanaged code. This can be done by PINNING the object.
See answer to this question.
No, since the object is allocated on C++ unmanaged heap GC won't touch it. You have to deallocate it yourself using delete.
Edit:
If you need to allocate an object in managed code and deallocate in unmanaged code or vice versa, It's good to know there is OS heap for this purpose that you can use via Marshal.AllocHGlobal and Marshal.FreeHGlobal calls from C#, there will be similar calls in C++.
It's really simple!
Depends
Depends
Eh, Sorry about that.
Under typical conditions, C# will keep track of the memory and get rid of it any time after it's no longer used on the C# side. It has no way of tracking references on the C++ side, so one common mistake in interop is that the memory is deallocated before the unmanaged side is done with it (resulting in loads of FUN). This only applies for cases where the memory is directly referenced, not when its copied (the typical case being a byte[] that's pinned for the duration of the unmanaged call). Don't use automatic marshalling when the life-time of the object/pointer being passed to unmanaged code is supposed to be longer than the run of the invoked method.
Under typical conditions, C# has no way of tracking memory allocations in the C++ code, so you can't rely on automatic memory management. There are exceptions (e.g. some COM scenarios), but you'll almost always need to manage the memory manually. This usually means sending the pointer back to the C++ code to do the deallocation, unless it used a global allocator of some kind (e.g. CoMemoryInitialize). Remember that in the unmanaged world, there is no one memory manager that you can safely invoke to dispose of memory; you don't really have the necessary information anyway.
This only applies to pointers, of course. Passing integers is perfectly fine, and using automatic marshalling usually means the marshaller takes care of most of the subtleties (though still only in the simplest case, so be careful). Unmanaged code is unmanaged - you need to understand perfectly how the memory is allocated, and how, when and who is responsible for cleaning up the memory.
As a rule of thumb, whichever component/object allocates memory should deallocate memory. For every new a delete by the one which did new.
That is the ideal. If not followed for reasons such as you C++ program may terminate and not exists when allocated memory's lifecycle comes to an end, your C# should clean up and visa versa.

Passing large data structures to unmanaged code using fixed pointer

I'm developing an application which consists of two parts:
C# front-end
C++ number cruncher
In some cases the amount of data passed from C# to C++ can be really large. I'm talking about Gb and maybe more. There's a large array of doubles in particular and I wanted to pass a pinning/fixed pointer to this array to C++ code. The number crunching can take up to several hours to finish. I'm worrying about any problems that can be triggered by this usage of pinning pointers. As I see it, the garbage collector will not be able to touch this large memory region for a long time. Can this cause any problems? Should I consider a different strategy?
I thought that instead of passing the whole array I could provide an interface for building this array from within C++ code, so that the memory is owned by unmanaged part of the application. But in the end both strategies will create a large chunk of memory which is not relocatable for C# garbage collector for a long time. Am I missing something?
You don't have a problem. Large arrays are allocated in the Large Object Heap. Pinning them can not have any detrimental effect, the LOH is not compacted. "Large" here means an array of doubles with 1000 or more elements for 32-bit code or any array equal or larger than 85,000 bytes.
For your specific use case, it may be worthwhile to use a memory mapped file as the shared memory buffer between your c# and c++ code. This circumvents the garbage collector altogether. And also lets the OS cache pager deal with memory pressure issues, instead of GC managed memory.

How to obtain remaining free stack / heap memory in C# using managed code?

Is there a way to obtain the remaining free stack / heap memory in C# using only managed code?
To be specific, I do not mean the memory that is still available in the currently allocated state but all the memory that (in the future) could be allocated (if necessary) based on the main memory of the host system.
The information will be used to take measures on systems with low free memory to prevent running out of system memory.
There is a method called virtualquery that can be used to determine the size of the call stack. There are a bunch of C# examples here.
Checking available stack size in C
Checking stack size in C#
For big heap allocations you could try the MemoryFailPoint which checks to see if allocation is possible and throws a different exception then OOM
http://msdn.microsoft.com/en-us/library/system.runtime.memoryfailpoint.aspx
Answer mainly covered by AbdElRaheim... additional note about heap for 32bit systems.
If you want to go all the way with checking space for heap allocations (BTW, somewhat interesting for non-x64 programs): you need not only total amount of free memory but also map of all regions and see what is already allocated. Most interesting piece of information you would be looking for is DLLs loaded into your address space - even having 1GB free does not mean you can allocate 1GB block - there could be multiple chunks that GC can't combine together if some random native DLL is loaded in the middle.
If you want to go that far - VirtualQuery is a possible starting point.

With the stack and heap parts of memory, which one is managed by the .NET garbage collector?

With the stack and heap parts of memory, which one is managed by the .NET garbage collector?
Memory on the heap is managed by the garbage collector. Memory on the stack is deterministic and is returned to the pool when it goes out of scope.
Just the (managed) heap. The stack may have references to objects, but not the objects themselves.
This depends on the level of abstraction you're considering. At a managed level, there is a single 'managed heap', but it is actually broken into separate buffers to support generational garbage collection. There is also an unmanaged heap, from which unmanaged code can allocate memory in blissful ignorance of the CLR. All of this is implemented with one underlying OS process memory space where all of the various heaps live.
The story is complicated by the fact that the GC can compact its various heaps as part of collection. When this happens, the GC moves memory around, which means pointers can be invalidated. In order to accomodate this, the GC reserves the right to modify references throughout the application to point to the correct location. In this sense, the GC manages the 'stack', too, since the references stored on the stack can change to where they are pointing.

What is the difference between C++ memory management and .NET memory management?

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.

Categories

Resources