GC.AddMemoryPressure

I am writing a C # application that uses a third-party COM-DLL, this DLL creates a lot of resources (for example, bitmaps, videos, data structures) in unmanaged memory. While digging, I came across the following call to the garbage collector:

GC.AddMemoryPressure(long long bytesAllocated) 

This is described on MSDN:

http://msdn.microsoft.com/en-us/library/system.gc.addmemorypressure.aspx

This is similar to what I should call, as this external dll creates a lot of resources that the CLR is not aware of.

I have two questions ...

  • How to find out what memory pressure needs to be added when the dll is a third-party, and I was not able to know exactly how much memory this dll allocates.
  • How important is this to do?
+6
garbage-collection c #
source share
4 answers

In any mixed native / managed process, there is a mixture of using native / managed memory. If there is no GC-controlled relationship between them, then this API is not needed. For example, if there are certain deterministic state changes in the managed code that cause the allocation and release of internal memory, then nothing that the GC can do will never force the memory to free.

However, very often there is a built-in memory stored in managed objects with finalizers. In this way, GC can reduce the size of the native heap, simply by launching the collection and launching these finalizers.

Therefore, if you have a lot of this, you may need to name this API (as the documentation says).

As for how much you should say this, this is probably not what you can prepare for pure analysis, especially with a third-party library. You need to run Performance Monitor, run a test that allocates many third-party objects, and look at the Native Bytes and CLR counts to see how they are related.

Since you are using a COM object, you can really determine the forced instances to clean up when you know that you no longer need them using Marshal.ReleaseComObject . Note that you need to use a dumb loop to get rid of the object:

 while (Marshal.ReleaseComObject(obj) != 0) { } 
+5
source share

Let's say I have an object like this:

 public class SomeImageType : IDisposable { public int Width { get; private set; } public int Height { get; private set; } public PixelFormat PixelFormat { get; private set; } IntPtr ImageData { get; private set; } // implementation of constructor and IDisposable not shown } 

How much memory does it take? 20 bytes + object overhead? When the time comes for collection, if this object has no links, it does not matter. But is it required 20 bytes? Hell no is an image. So take 20 and multiply them by the width, height and number of bytes per pixel, and you have something that takes (possibly) megabytes. Speaking to GC, to add pressure to your memory, you say that there the iceberg was chewing resources there. When you delete an object, you will of course free this memory and tell GC to release this pressure. These two calls allow you to hint at GC that there are strange things in circle K, and perhaps he would like to plan the collection in different ways.

+3
source share

The most important thing you can do is call the Dispose () method for these third-party DLL classes and be absolutely fanatical about it. (Or, of course, using the β€œuse” of blocks, as they automatically call Dispose () when they exit the block.)

The thing about unmanaged resources is that the .NET classes that wrap or use them require the hava finalizer, as well as the implementation of the IDisposable () template. If Dispose () is called, it must take care of unmanaged resources immediately, and it must also suppress the finalizer. If you do not call Dispose (), you are having problems with real memory, and adding β€œpressure” to the garbage collector will not fix it.

The main logic of the garbage collector is that any class that has an active finalizer is not processed until all other possibilities are exhausted. This means that the cleanup of gen0, gen1 and gen2 has already occurred. A finalizer that has not been suppressed is almost as bad as a memory leak.

So the call to Dispose (). Make sure you never miss.

EDIT: Just noticed that a third-party DLL is a COM library. Best practice is to make sure your .NET wrappers fully implement IDisposable () (not just providing the Dispose method). Then, make sure you always call Dispose () when you are done with COM objects.

+2
source share

This is not important for you if you do not notice the memory problems that you think are caused by the GC.

+1
source share

All Articles