Main Site Documentation

Why OutOfMemoryException?


#1

This may seem like a pointless question because I am intentionally writing an example of what NOT to do. But, still, I don’t understand why it should result in the error I’m getting unless there is a memory leak somewhere.

If I let this run for a minute or so and click the button several times along the way, it will eventually result in:

Any explainations for this?

    public partial class Program
    {
        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            Debug.Print("Program Started");

            button.ButtonPressed += button_ButtonPressed;

            var timer = new GT.Timer(200);
            timer.Tick += new GT.Timer.TickEventHandler(timer_Tick);
            timer.Start();
           // return;

            while (true)
            {
                Debug.Print("Button State = " + button.IsPressed);
                Thread.Sleep(200);
            }
        }

        void timer_Tick(GT.Timer timer)
        {
            PulseDebugLED();
        }

        void button_ButtonPressed(GTM.GHIElectronics.Button sender, GTM.GHIElectronics.Button.ButtonState state)
        {
            Debug.Print("Animate!");
            led7r.Animate(20, true, true, false);
        }
    }


#2

Does it throw the exception when you do it the right way?


#3

No, there’s no problem if I don’t put the loop in ProgramStarted().


#4

Is it the first iteration, a specific number of iterations, or does it vary before you get the exception?

I have never used the PulseDebugLed, does it cause the light to turn on and then off? If so you have at least 15 timed events running every second and depending on the duration they might be tripping over each other.


#5

[quote=“PintSize.Me”]I have never used the PulseDebugLed, does it cause the light to turn on and then off? If so you have at least 15 timed events running every second and depending on the duration they might be tripping over each other.
[/quote]

Yes, that’s what PulseDebugLed does. However, the point of this example is that PulseDebugLed will never get called because of the while loop in ProgramStarted.

If I extend the length of the Timer then it takes longer to get the exception. So, I think the answer to this question is that the timer runs on it’s own thread and continues to tick and queue up events until it eventually runs out of memory because it cannot deliver them due to the while loop. My previous belief was that the timer wouldn’t start to queue up events until after we exited ProgramStarted() but I don’t believe this is the case now.


#6

ian,
it could also be that ProgramStarted is running on the dispatcher thread (just a guess). If so, then since Gadgeteer Timer also executes tick event code on the dispatcher thread (which i’m pretty sure it does), then those will never get processed since the endless while loop in ProgramStarted is effectively blocking that dispatcher thread…eventually you will run out of memory, as you noted, due to backed up events.

you probably could solve this by using a normal thread instead of the the GT timer if the code does not need to be executed on the dispatcher thread.

edit: come to think of it, it may not even have to be dispatcher related…it could also be that, based on the code, the timer and other objects are initialized on the same thread that programstarted is run on…the thread that the while loop is blocking…and consequently blocking any queued event handling on that thread.


#7

just an idea,
maybe the loop is blocking the gc ?


#8

I would agree with Dizzy, its probably the timer events getting stacked up in the background and not being executed due to the loop.

What happens if you leave it running but never press the button?

Paul


#9

Yes, I think we’re all in agreement on this now. Thanks.