James Aharon
James Aharon

Reputation: 223

Why i'm getting OutOfMemoryException?

I have this method i'm calling the method each X seconds from a timer tick event. In the first few seconds there are no problems but then after 20 seconds or it show the exception.

private void ReturnTexture(Texture texture_take, List<Point> lstPnt, float[] anglArr, float angle)
        {
            int i, j, bytes = 2048 * 512, stride = 2048;
            GraphicsStream textureStream;
            byte[] rgbValues = new byte[bytes];

            //sets texture to complete transparent
            GCHandle gch = GCHandle.Alloc(rgbValues, GCHandleType.Pinned);
            MemSet(gch.AddrOfPinnedObject(), 0x0, rgbValues.Length);

            //add 90 degrees because the cone starts at 90
            angle += 90F + 23.75F;

            //checks all points and draws yellow only those how are inside the cone
            if (lstPnt != null)
            {
                for (i = 0; i < lstPnt.Count - 1; i++)
                {
                    if (anglArr[i] <= angle && anglArr[i] >= angle - 47.5F) //if point angle is inside cone. Cone angle is 47.5 degrees
                    {
                        j = lstPnt[i].Y * stride + lstPnt[i].X * 4;

                        //yellow
                        rgbValues[j + 0] = (byte)0;
                        rgbValues[j + 1] = (byte)255;
                        rgbValues[j + 2] = (byte)255;
                        rgbValues[j + 3] = (byte)255;
                    }
                    else
                    {

                    }
                }
            }

The exception is on the line:

byte[] rgbValues = new byte[bytes];

When the exception happen i see that the variable bytes contain: 1048576 And rgbValues is null

I used a breakpoint before the exception happen and saw that the value in bytes was the same: 1048576 but the exception happen only after 20 seconds or so and not just in the beginning.

An unhandled exception of type 'System.OutOfMemoryException' occurred in Weather Radar.exe

System.OutOfMemoryException was unhandled
  HResult=-2147024882
  Message=Exception of type 'System.OutOfMemoryException' was thrown.
  Source=Weather Radar
  StackTrace:
       at Weather_Radar.Form1.ReturnTexture(Texture texture_take, List`1 lstPnt, Single[] anglArr, Single angle) in d:\C-Sharp\Weather Radar\Weather Radar\Weather Radar\Form1.cs:line 314
       at Weather_Radar.Form1.timer1_Tick(Object sender, EventArgs e) in d:\C-Sharp\Weather Radar\Weather Radar\Weather Radar\Form1.cs:line 59
       at System.Windows.Forms.Timer.OnTick(EventArgs e)
       at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Weather_Radar.Program.Main() in d:\C-Sharp\Weather Radar\Weather Radar\Weather Radar\Program.cs:line 19
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

Line 314 in form1 is: byte[] rgbValues = new byte[bytes];

Line 59 in form1 is: ReturnTexture(scannedCloudsTexture, cloudPoints, angleArray, angleF);

This is the timer tick event code:

static float angle_ = 0.0F;
        static float angleF = 0.0F;
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (angleF > 360F)
            {
                angleF -= 360F;
            }

            ReturnTexture(scannedCloudsTexture, cloudPoints, angleArray, angleF);

            DisplayOnScreen(angle_);

            angle_ += (float)(Math.PI * 1d / 180d);
            angleF += 1.0F;
        }

Upvotes: 0

Views: 866

Answers (1)

Bas
Bas

Reputation: 27085

As explained in the comment by Renuiz, it looks like you are not freeing memory allocated for your image. When you call GCHandle.Alloc

A new GCHandle that protects the object from garbage collection. This GCHandle must be released with Free when it is no longer needed.

If you do not Free the GCHandle, the 1MB allocated by your code will never be released. I think there are two possible options:

  • Reuse the byte[] if possible, not requiring more memory. Keep the GCHandle so you can memset them to zeroes each tick.
  • Do not pin the byte[] in memory using the GCHandle. When you create a new byte[] all values will be set to zero anyways.

Upvotes: 1

Related Questions