Yield memory allocation

I use similar code to turn off / on a set of game objects in a looped sequence, with delays between.

Works great but it allocates runtime memory. Its pretty slow, the used stack only increases every 20 seconds or so, but it does continue to accumulate and eventually leads to GC.

Can anybody explain why, and is there anything that can be done about it?

var delayTime = 2.0;

function Start () 
{
   while (true)
   {
   	yield DoStuff ();
   }
}

function DoStuff ()
{

    // do stuff
    yield WaitForSeconds (delayTime);
}

There might be some code in your //do stuff that allocates memory. Did you check that?

simply because you put in an object (the return of the function an IEnumerator as you can see on C#)

each yield receives something that will be disposed at some point afterwards.
Just because JS hides what it does, that does not mean that it can get around of it

@Peter
I thought about that, but no. I was simply activating and deactivating cached gameObjects, which I don’t believe should do anything.

As is, the code above actually generates allocations. I just boiled it down to basics to eliminate the variables you mentioned.

@Dreamora

I don’t know much about C#, but it sounds like you’re saying is the use of yield generates runtime objects that eventually have to get dumped.

Short answer is no, nothing to be done?

There is nothing you can do other than remove the yield statements unless you can cache the WaitForSeconds which I don’t know if you can, but it is an object so it might be possible.

Yes, the use of yield does generate new runtime objects like he said. Here’s what the code would be in C#

yield return new WaitForSeconds(3);

As you can see the coroutine is generating a new IEnumerator.

interesting.

So, are those objects autodestroyed after the yield is complete? Or do they get garbage collected? Or what?

there is no such thing as autodestroy

all stuff created will be garbage collected when no longer used

Interesting. Looks like C# is much more transparent about whats going on underneath the hood.

Can’t remove the yield in this case… unless there’s another way to do a looping sequence of events.

I’ll see if its possible to cache WaitForSeconds.

Thanks all.

Maybe create your own counter to wait n seconds (or n frames)?

That’s what I ended up doing and got everything running in an update loop.

yield does offer quick and easy solutions to certain problems but at the cost of heap allocations (small as they are). Buyer beware!

[irony]Yeah a heap allocation of a few bytes is worse than polling countless cpu cycles[/irony]

if you are that worried, take yield null and do the not even remotely smart polling approach that way, but normally you would really just use WaitForSeconds and wait your time, you won’t die with that amount of allocation in any way nor see an impact on the performance.

Unlike you will from the presence of an update function without even having anything in

Depends what you’re using things for. You can’t get around allocations for coroutines. If you’re doing a yield WaitForSeconds, it’s generally not going to cause many allocations to have a big problem. If you’re just calling yield; in a while loop, you should probably just do polling. If you’re using it to sync with character animation, just use animationevents instead.

if you are doing yield in a while loop, you would optimally use yield null, that does not allocate anything