Solved

Seriously Evil Memory Leak.

Posted on 2004-04-04
2
714 Views
Last Modified: 2012-06-22
I have a memory leak, and it may be in one spot or a dozen (I need help). The problem is, 3 secs after launching, the program eats up about 2GB of memory. Fun!

This class is supposed to capture a window from the desktop, and pass back a screenshot of it. It is called about 30 times a sec (for rapid updates). Instead it goes to lunch on my machine. Any help?


public class Capture
      {
            /*
                  
            public void captureScreen(string fileName,ImageFormat imageFormat)
            {
                  int hdcSrc = User32.GetWindowDC(User32.GetDesktopWindow()),
                        hdcDest = GDI32.CreateCompatibleDC(hdcSrc),
                        hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc,
                        GDI32.GetDeviceCaps(hdcSrc,8),GDI32.GetDeviceCaps(hdcSrc,10));
                  GDI32.SelectObject(hdcDest,hBitmap);
                  GDI32.BitBlt(hdcDest,0,0,GDI32.GetDeviceCaps(hdcSrc,8),
                        GDI32.GetDeviceCaps(hdcSrc,10),
                        hdcSrc,0,0,0x00CC0020);
                  SaveImageAs(hBitmap,fileName,imageFormat);
                  Cleanup(hBitmap,hdcSrc,hdcDest);
            }
            */
            public void drawWindow()
            {
                  Gl.glEnable(Gl.GL_TEXTURE_2D);
                  Gl.glPushMatrix();
                  Gl.glTranslatef(0F, 0F, -20F);
                  Gl.glBindTexture(Gl.GL_TEXTURE_2D, this.Texture);
                  Gl.glBegin(Gl.GL_QUADS);
                  Gl.glNormal3f( 0.0f, 0.0f, 1.0f);
                  Gl.glTexCoord2f(1.0f, 1.0f); Gl.glVertex3f(14.16f, 9.4405f,  0.0f);  //10.345
                  Gl.glTexCoord2f(0.0f, 1.0f); Gl.glVertex3f(-14.16f, 9.4405f,  0.0f);//0.7045
                  Gl.glTexCoord2f(0.0f, 0.0f); Gl.glVertex3f(-14.16f,  -8.8405f,  0.0f);
                  Gl.glTexCoord2f(1.0f, 0.0f); Gl.glVertex3f(14.16f,  -8.8405f,  0.0f);
                  Gl.glEnd();
                  Gl.glTranslatef(0F, 0F, 20F);
                  Gl.glPopMatrix();
                  //Gl.glDisable(Gl.GL_TEXTURE_2D);

            }

            public void updateWindow()
            {
                  
                  unLoadTexture();
                  
                  //GDI32.SelectObject(HdcDest,HBitmap);
                  GDI32.BitBlt(HdcDest,0,0,GDI32.GetDeviceCaps(HdcSrc,8),
                        GDI32.GetDeviceCaps(HdcSrc,10),
                        HdcSrc,0,0,0x00CC0020);

                  Bitmap image =
                        new Bitmap(Image.FromHbitmap(new IntPtr(HBitmap)),
                        Image.FromHbitmap(new IntPtr(HBitmap)).Width,
                        Image.FromHbitmap(new IntPtr(HBitmap)).Height);

                  Bitmap image2 = new Bitmap(NWidth, NHeight);
                  Graphics g = Graphics.FromImage(image2);
                  g.DrawImage(image, new Rectangle(0,0,NWidth,NHeight),0,0,
                        NWidth,NHeight,GraphicsUnit.Pixel);
                  g.Dispose();

      

                  this._window = image2;
                  loadTexture();
            }

            public void updateSize()
            {
                  User32.GetWindowRect(HWnd, ref this._client);
                  this._nWidth = this._client.Right - this._client.Left;
                  this._nHeight = this._client.Bottom - this._client.Top;

            }
            
            public Capture(IntPtr hWnd2)
            {      
                  this._hWnd = hWnd2;
                  User32.GetWindowRect(HWnd, ref this._client);
                  this._nWidth = this._client.Right - this._client.Left;
                  this._nHeight = this._client.Bottom - this._client.Top;
                              
                  this._hdcSrc = User32.GetWindowDC(HWnd.ToInt32());
                  this._hdcDest = GDI32.CreateCompatibleDC(HdcSrc);
                  this._hBitmap = GDI32.CreateCompatibleBitmap(HdcSrc,
                        GDI32.GetDeviceCaps(HdcSrc,8),GDI32.GetDeviceCaps(HdcSrc,10));       
                  GDI32.SelectObject(HdcDest,HBitmap);
                  GDI32.BitBlt(HdcDest,0,0,GDI32.GetDeviceCaps(HdcSrc,8),
                        GDI32.GetDeviceCaps(HdcSrc,10),
                        HdcSrc,0,0,0x00CC0020);

                  Bitmap image =
                        new Bitmap(Image.FromHbitmap(new IntPtr(HBitmap)),
                        Image.FromHbitmap(new IntPtr(HBitmap)).Width,
                        Image.FromHbitmap(new IntPtr(HBitmap)).Height);

                  Bitmap image2 = new Bitmap(NWidth, NHeight);
                  Graphics g = Graphics.FromImage(image2);
                  g.DrawImage(image, new Rectangle(0,0,NWidth,NHeight),0,0,
                        NWidth,NHeight,GraphicsUnit.Pixel);
                  g.Dispose();

                  this._window = image2;
                  
            }
            public void unLoadTexture()
            {
                  Gl.glDeleteTextures(1, ref this._texture);
            }

            public void loadTexture()
            {                              
                  using(Bitmap bitmap = new Bitmap(this.Window))
                  {
                        bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
                        
                        Rectangle rectangle = new Rectangle(0, 0, bitmap.Width,
                              bitmap.Height);
                        BitmapData bitmapData = bitmap.LockBits(rectangle,
                              ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                              
                        Gl.glGenTextures(1, out this._texture);
                        Gl.glBindTexture(Gl.GL_TEXTURE_2D, this._texture);
                        Gl.glTexParameteri(Gl.GL_TEXTURE_2D,
                              Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                        Gl.glTexParameteri(Gl.GL_TEXTURE_2D,
                              Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR);
                        Glu.gluBuild2DMipmaps(Gl.GL_TEXTURE_2D, 3,
                              bitmapData.Width, bitmapData.Height,
                              Gl.GL_BGR_EXT, Gl.GL_UNSIGNED_BYTE,
                              bitmapData.Scan0);
                        bitmap.UnlockBits(bitmapData);
                  }
            }
            private void cleanup(int hBitmap,int hdcSrc,int hdcDest)
            {
                  User32.ReleaseDC(User32.GetDesktopWindow(),hdcSrc);
                  GDI32.DeleteDC(hdcDest);
                  GDI32.DeleteObject(hBitmap);
            }      

            private void saveImageAs(int hBitmap,string fileName,ImageFormat imageFormat)
            {
                  Bitmap image =
                        new Bitmap(Image.FromHbitmap(new IntPtr(HBitmap)),
                        Image.FromHbitmap(new IntPtr(HBitmap)).Width,
                        Image.FromHbitmap(new IntPtr(HBitmap)).Height);
                  image.Save(fileName,imageFormat);
            }

            public Bitmap Window
            {
                  get
                  {
                        return _window;
                  }

            }
            public int NWidth
            {

                  get
                  {
                        return _nWidth;
                  }
            }
            public IntPtr HWnd
            {

                  get
                  {
                        return _hWnd;
                  }
            }
            public int NHeight
            {
                  get
                  {
                        return _nHeight;
                  }
            }
            public int HdcDest
            {
                  get
                  {
                        return _hdcDest;
                  }
            }
            public int HdcSrc
            {
                  get
                  {
                        return _hdcSrc;
                  }
            }
            public int HBitmap
            {
                  get
                  {
                        return _hBitmap;
                  }
            }
            public int Texture
            {
                  get
                  {
                        return _texture;
                  }
            }

            private Bitmap _window;
            private IntPtr _hWnd;
            private int _nWidth;
            private int _nHeight;
            private int _hdcDest;
            private int _hdcSrc;
            private int _hBitmap;
            private int _texture;
            private RECT _client = new RECT();

      }
0
Comment
Question by:rossryan
2 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 500 total points
ID: 10755138
I see that you have cleanup function, do you call it? Capture function creates graphic objects:

              this._hdcSrc = User32.GetWindowDC(HWnd.ToInt32());
              this._hdcDest = GDI32.CreateCompatibleDC(HdcSrc);
              this._hBitmap = GDI32.CreateCompatibleBitmap(HdcSrc,
                   GDI32.GetDeviceCaps(HdcSrc,8),GDI32.GetDeviceCaps(HdcSrc,10));      

They should be released after each call to Capture function.
0
 

Author Comment

by:rossryan
ID: 10755161
Isolated the problem. Update() keeps creating new bitmaps without killing the old ones.
0

Featured Post

Secure Your Active Directory - April 20, 2017

Active Directory plays a critical role in your company’s IT infrastructure and keeping it secure in today’s hacker-infested world is a must.
Microsoft published 300+ pages of guidance, but who has the time, money, and resources to implement? Register now to find an easier way.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In order to hide the "ugly" records selectors (triangles) in the rowheaders, here are some suggestions. Microsoft doesn't have a direct method/property to do it. You can only hide the rowheader column. First solution, the easy way The first sol…
This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

685 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question