Work with unmanaged resources

I use a third-party library, which is a wrapper around the native DLL. the library contains the XImage type, XImage has some properties and the IntPtr Data() method. XImage also implements IDisposable , but I do not know if it is implemented correctly.

I get a lot of XImage from a TCP connection and show them as a movie in a PictureBox .

I used to convert 'XImage' to System.Drawing.Image and looked at them in a PictureBox , but got an AccessViolationException .

So, I did a wrapper around XImage called Frame .

 public class Frame : IDisposable { public uint size { get; private set; } private Image image; public XImage XImage { get; set; } public Image Image { get { return image ?? (image = GetBitmap(this.XImage)); } } public DateTime Time { get; set; } public Frame(XImage xImage) { this.XImage = xImage; this.size = XImage.ImageBufferSize(); GC.AddMemoryPressure(size); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~Frame() { Dispose(false); } protected virtual void Dispose(bool disposing) { if (disposing) { try { image.Dispose(); } catch { } finally { image = null; } try { MImage.Dispose(); } catch { } finally { XImage = null; } } GC.RemoveMemoryPressure(size); } } 

and handling Frame references, I resolved an AccessViolationException . now I have one more problem when I run the program from visual studio (F5 - Start Debugging), everything is fine, but when I run it from the .exe or (ctrl + F5 - Start without debugging), the memory usage grows all more and more until I get an OutOfMemoryException . (Biuld Configuration: Release - X86). what should I do?

---- EDIT ----

I found that GC.AddMemoryPressure or GC.RemoveMemoryPressure just makes garbage collection work more often, and now my problem is that I have small objects that have a large unmanaged memory descriptor, and GC does not collect these small objects.

---- EDIT ----
calling GC.Collect will solve the problem at runtime, I periodically set the timer and call GC.Collect , but this makes the application freeze for a short period, so I do not want to use this approach.

+4
source share
1 answer

I found that the GC has limitations and may not work too well under very strong pressure and for heavy memory use. I have an application that does nothing with unmanaged resources directly, with all standard .NET components, and can still be choked in memory. It can use GB of RAM, but not because of the huge memory needs, but because large objects are created and destroyed relatively quickly and, apparently, are not collected too often. The application has no memory leaks as it is freed when collection is forced. It seems that the GC cannot always collect unused objects on time, i.e. before an OutOfMemoryException . He waits to find a better moment, but before he decides it is already too late. When I periodically force a collection, the application starts without problems.

It is worth noting that an OutOfMemoryException does not always mean that you are really free of memory. This may also mean that there are not enough adjacent memory blocks. This may be the case, especially when working with video and images. GC might think that there is still a lot of free space in memory, but it is too fragmented for your application. I am sure that the GC takes fragmentation into account, but it is possible that this is not always correct.

If you are sure that the library is not a problem, I advise you to experiment more with memory pressure methods ( AddMemoryPressure and RemoveMemoryPressure ) to help the GC complete its action on time. It can solve your problems since you are working with an unmanaged library that can process a significant portion of the memory behind the GC back. Alternatively, do the same as with GC.Collect . Manual picking may not be ideal, but I think there are times when it is warranted. Of course, expect that manually collecting multiple objects can affect the performance of your application.

EDIT

If manual collection affects performance too much, try using overloaded versions of GC.Collect , which give you a little more control.

0
source

Source: https://habr.com/ru/post/1412226/


All Articles