Garbage Collection and lists

Is it safe to cache lists outside a function so they won’t be created everytime the function gets called??

My game is fairly simple in design I have a maingame controller which calls a never ending coroutine each second to update Economy/Politics/Upkeeps/Unit stats/AI states. I get 8-40kb garbage on the 60th frame.
90% of that is because of arrays/lists.

Also what is the recomended garbage limit??

Yes.

Why bother with a coroutine if you can just use Update()? Or just have Update() call another function that you created?

1 Like

I want the updates to occur every second, so I will need a way to time them I haven’t though of anything better that coroutines. Is there a better way??

Thanks for helping!

You could use a timer variable in Update() like so:

currentTime -= Time.deltaTime; 

if (currentTime <= 0)
{
   // do something
   currentTime += 1;  // or however many seconds
}

Actually, how exactly were you calling the coroutine each second? Or is the coroutine itself just waiting for a second before looping? I may have misunderstood when you said you were calling it each second.

1 Like

Yep.

And I want to add to the discussion, what I went and did was create a class for this specific job. It’s a little weird, but it helps a lot in unity where GC can hit you hard (especially on arrays/collections).

TempList:
https://github.com/lordofduct/spacepuppy-unity-framework-3.0/blob/master/SpacepuppyUnityFramework/Collections/TempList.cs

This class has a cache pool that recycles lists. You can call the static ‘GetList’ method to get a new list, and when it gets disposed it’s placed back in the pool.

Here is the ‘ObjectCachePool’ implementation as well:
https://github.com/lordofduct/spacepuppy-unity-framework-3.0/blob/master/SpacepuppyUnityFramework/Collections/ObjectCachePool.cs

A simple example might be something like:

//when a 'using' clause ends, it automatically calls dispose on the variable you set as 'using'
using(var lst = TempList<Component>.GetList())
{
    this.gameObject.GetComponents<Component>(lst); //using the special non-allocating GetComponents method from unity

    foreach(var c in lst)
    {
        //do something with c
    }
}
1 Like

I call the coroutine once in Start() and I have a while(true) with a cached WaitForSeconds. Yeah the way I described the coroutine call was a little misleading.

I believe your Update approach to be slightly more efficient but isn’t waitForSeconds more accurate that update timer?? Or is it the same thing timewise??

No, it’s no more accurate. A coroutine won’t return exactly at the time duration set. But rather at the beginning of the frame just following that duration.

1 Like

Thanks a lot guys I will check the TempList implementation and consider moving my code to the update instead of using a coroutine.

ps. I don’t know why but I was always under the impression that coroutines ran independantly from Update() with a better accuracy. Thanks again for the help!

Depends on yur code. Does it need to run every frameor just once on every nth second? Try InvokeRepeating then

I’m curious, are you intentionally using the word “cache”? It sounds as if the normal thing your coroutine wants to do is store one big list as a global, which it works on a little each time. Most people wouldn’t call that caching – it’s just using a global.

I’m wondering if you wanted to do that, but heard functions can’t, so rejiggered it to needlessly remake the same list each time. And now you’re asking “I heard functions shouldn’t use and change script variables. Is that true?”

No I just need to locally create some data collections to perform some calculations. Those functions are called periodically and I thought declaring the collection outside function so they won’t be created destroyed on every call. Specifically I define them as private static.