When allocating memory from unmanaged process memory using Marshal.AllocHGlobal will the allocated memory address not change during the life of the application?
Am I correct in assuming that the memory block will exist until I call Marshal.FreeHGlobal and its address is unchanged?
Related
I am trying to debug strange memory leak in C# application (uses c++/cli and c++) using Diagnostic tool and Memory usage snapshots. But i have discovered one strange problem.
When I run debug in VS2017 with Heap Profiling turned on memory consumption is constant and program runs as expected. When Heap Profiling is turned off program leaks memory which has linear increase. Work completed is same, i have progress of work printed in console and I am sure both programs have made the same work, but one uses constant memory and other has linearly increasing memory (when same work done 2x memory used). Visually it looks like when GC is fired with Heap Profiling some memory gets released, and no memory is released when Heap Profiling is not used.
Does anyone have idea how could Heap Profiling affect this? Native memory is leaked.
[EDIT1] Data from Performance Profiler -> Memory usage
Object Type Reference Count Module
shared_ptr_cli<GeoAtomAttributes> TestBackEnd64.dll
shared_ptr_cli<GeoAtomAttributes> [Finalization Handle] 856,275 TestBackEnd64.dll
shared_ptr_cli<GeoAtomAttributes> [Local Variable] 1 TestBackEnd64.dll
GeoAtomAttributesCli [Local Variable] 1 TestBackEnd64.dll
Memory that can be relased with gc should not be considered as leaked memory, it should be considered as memory that is eligible for garbage collection. Because the next time gc is performed this memory will be collected and available for new object allocations.
Other thoughts;
Gc runs on managed heap, native libraries allocates memory on the native heap. So It cannot effect the memory management of native libraries. But you should be aware of the following cases.(this might not be your case though)
If you pass pinned data structures to native code and free these handles on your Object.Finalize method (of wrapper class); in this case the pinned memory can only be collected when wrapper class is queued for finalization.Calling cleanup functions(*) of native code in the finalize method of managed class can also cause similar cases. I think these are bad practices and should not be used, instead these cleanups should be done as soon as possible.
(*) This case might cause your total process memory consumption to bloat even when there is no need for gc in the managed heap.
In my C# program i have function that in it, i create array of Byte with length of 1000000 and when the function executed , memory show 1MB increase in memory usage.
The problem is here, after returning from function , 1MB memory that allocated in function does not release , WHY????
Garbage collector doesn't free up memory right away but
Garbage collection occurs when one of the following conditions is true:
The system has low physical memory. This is detected by either the low memory notification from the OS or low memory indicated by the host.
The memory that is used by allocated objects on the managed heap surpasses an acceptable threshold. This threshold is continuously adjusted as the process runs.
The GC.Collect method is called. In almost all cases, you do not have to call this method, because the garbage collector runs continuously. This method is primarily used for unique situations and testing.
You can find more here.
I have a c# library that P/Invokes into an unmanaged library. I allocate resources in the unmanaged memory, send them to the managed code, make a copy and then send it back for freeing by the unmanaged code. This apparently is leaking memory, so i want to a quick way in c# to determine the currently allocated memory and which changes as we free memory.
I tried using Process.GetCurrentProcess().PagedSystemMemorySize64, it shows that i have a memory leak, but i want to make sure this property reflects that i freed the memory or not.
Thanks in advance.
I'd like to do Marshal.AllocHGlobal in managed code, fill it with data, and pass that memory block to unmanaged (C++) code that will then be responsible for freeing it.
Under the hood, Marshal.AllocHGlobal calls LocalAlloc (and, I'm guessing, LocalLock). But in order for the unmanaged code to call LocalFree, it needs the HLOCAL returned by LocalAlloc, which Marshal.AllocHGlobal doesn't provide.
I'm not necessarily restricted to using AllocHGlobal; the high level goal is to let the managed code allocate memory that the unmanaged code and then read and free.
This is not a handle, not since Windows version 3. Calling LocalFree() on the pointer is fine, as the Windows SDK article shows in its example. Marshal.AllocCoTaskMem and CoTaskMemFree() are the better mouse trap here.
I am using Red Gates ANTS memory profiler to debug a memory leak. It keeps warning me that:
Memory Fragmentation may be causing
.NET to reserver too much free memory.
or
Memory Fragmentation is affecting the size of the largest object that can be allocated
Because I have OCD, this problem must be resolved.
What are some standard coding practices that help avoid memory fragmentation.
Can you defragment it through some .NET methods? Would it even help?
You know, I somewhat doubt the memory profiler here. The memory management system in .NET actually tries to defragment the heap for you by moving around memory (that's why you need to pin memory for it to be shared with an external DLL).
Large memory allocations taken over longer periods of time is prone to more fragmentation. While small ephemeral (short) memory requests are unlikely to cause fragmentation in .NET.
Here's also something worth thinking about. With the current GC of .NET, memory allocated close in time, is typically spaced close together in space. Which is the opposite of fragmentation. i.e. You should allocate memory the way you intend to access it.
Is it a managed code only or does it contains stuff like P/Invoke, unmanaged memory (Marshal.AllocHGlobal) or stuff like GCHandle.Alloc(obj, GCHandleType.Pinned)?
The GC heap treats large object allocations differently. It doesn't compact them, but instead just combines adjacent free blocks (like a traditional unmanaged memory store).
More info here: http://msdn.microsoft.com/en-us/magazine/cc534993.aspx
So the best strategy with very large objects is to allocate them once and then hold on to them and reuse them.
The .NET Framework 4.5.1, has the ability to explicitly compact the large object heap (LOH) during garbage collection.
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
See more info in GCSettings.LargeObjectHeapCompactionMode