I can not figure out why the memory leaks into the application (winform, .net). I use GdPicture.Net for text recognition, in one cycle (about 200 function calls from GdPicture.dll) as a whole grows by 20 MB. Here is the data from the VisualStudio profiler. the first moment of time and the second. conditionally the first moment of time

conditionally second moment of time

The function with the allocation of the largest memory looks like this ( no way )

enter image description here

I don’t know where to dig; in the code I ’m working carefully, wherever I need to implement the IDisposable interface. I do not even know what exactly to put out of the code in order to understand. I will be glad to any help.

public class OCRReader : IDisposable { private GdPictureImaging oGdPictureImaging = new GdPictureImaging(); private int m_ImageID; //[System.Runtime.InteropServices.DllImport("shell32.dll", EntryPoint = "ShellExecuteA")] //private static extern int ShellExecute(int hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd); public void Dispose() { if (oGdPictureImaging == null) return; oGdPictureImaging.OCRTesseractClear(); oGdPictureImaging.Dispose(); } public string ImageProccessing(int sourceX, int sourceY, int distinationX, int distinationY, int quality, bool saveImg = false, string name = "Empty") { try { LicenseManager oLicenceManager = new LicenseManager(); oLicenceManager.RegisterKEY("0429254382496276761391972"); using (MemoryStream memory = new MemoryStream()) { using (Bitmap bmp = new Bitmap(distinationX, distinationY)) { Rectangle rect = new Rectangle(sourceX, sourceY, distinationX, distinationY); Graphics graphics = Graphics.FromImage(bmp as Image); graphics.CopyFromScreen(rect.Left, rect.Top, 0, 0, bmp.Size); bmp.Save(memory, ImageFormat.Jpeg); if (memory != null) { if (GdPictureDocumentUtilities.GetDocumentFormat(memory) == DocumentFormat.DocumentFormatPDF) { GdPicturePDF oPDF = new GdPicturePDF(); if (oPDF.LoadFromStream(memory) == GdPictureStatus.OK) { m_ImageID = oPDF.RenderPageToGdPictureImageEx(200, true); if (m_ImageID == 0) return "File could not be loaded. Error: " + oPDF.GetStat().ToString(); oPDF.CloseDocument(); } } else { m_ImageID = oGdPictureImaging.CreateGdPictureImageFromStream(memory, DocumentFormat.DocumentFormatJPEG); if (m_ImageID == 0) return "Image could not be loaded. Error: " + oGdPictureImaging.GetStat().ToString(); } } if (oGdPictureImaging.Scale(m_ImageID, quality, System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic) != GdPictureStatus.OK) return "Error: " + oGdPictureImaging.GetStat().ToString(); string sOCR = null; int ncpt = 0; int LeftArea = 0; int TopArea = 0; OCRContext context = OCRContext.OCRContextSingleLine; oGdPictureImaging.OCRTesseractSetOCRContext(context); if (oGdPictureImaging.OCRTesseractReinit() != GdPictureStatus.OK) { return "Error" + " " + oGdPictureImaging.GetStat().ToString(); } sOCR = oGdPictureImaging.OCRTesseractDoOCR(m_ImageID, "eng", "OCR\\", ""); if (oGdPictureImaging.GetStat() == GdPictureStatus.OCRDictionaryNotFound) { return "Needed dictionary is not into the specified path!"; } else { oGdPictureImaging.OCRTesseractClear(); return sOCR; } } } } catch { return string.Empty; } }} 

Well, let the call about something like this

  using (OCRReader ocr = new OCRReader()) { for (int i = 0; i < 100; i++) { var val0 = ocr.ImageProccessing(100+i, 292, 53, xdestination, 220); } } 

Regarding this example, the more i, the more memory is allocated in one cycle.

  • One thing is to implement the interface in its class, another is the correct use of its methods in the application code. - Nikolay
  • 3
    The fact that the type implements IDisposable does not mean that the seized resource will be freed by the garbage collector. - tym32167
  • @ tym32167 wherever I use an object of this class, I enclose it in "using" as far as I know, which means that it will cause Dispose. Or not? - Yury Bakharev
  • 2
    Garbage collection in .NET is non-deterministic. You can’t talk about a leak between two iterations of a loop. Leakage is when memory consumption continues to grow for a long time, and something prevents the garbage collector from releasing this memory. - PashaPash
  • one
    And yes, IDisposable has nothing to do with the release of managed memory (memory allocated for objects). IDisposable is a way to control unmanaged resources (open file handles, for example). From the perspective of runtime, IDisposable is no different from other interfaces and its implementation doesn’t affect garbage collection and freeing memory. - PashaPash

0