Forum Discussion
Ablaze
9 years agoExplorer
[FREE Unity Plugin] Memory Efficient Coroutines
A lot of VR environments require movement, and a lot of movement is done in Unity using coroutines. However, many people don't know that coroutines allocate about .1kb of memory on the heap per running coroutine per frame. The garbage collector has to come clean that up later which causes random framerate spikes. If you use a bunch of coroutines then these spikes can end up happening more than once per minute. We all know that framerate is a very important issue in VR environments.
That's why I've released Memory Efficient Coroutines for free on the asset store. It produces zero per-frame allocations and can easily replace Unity's coroutines in your project. I hope that everyone who sees this will try it, and if you do please leave a review or at least a star rating. Thank you.
That's why I've released Memory Efficient Coroutines for free on the asset store. It produces zero per-frame allocations and can easily replace Unity's coroutines in your project. I hope that everyone who sees this will try it, and if you do please leave a review or at least a star rating. Thank you.
9 Replies
Replies have been turned off for this discussion
- petereptProtegeHi,
Since no-one has said thank you, I'll just take a moment to say "Thank you!". It's this kind of work that is a key contributor to everyone producing better and more consistent Unity experiences.
Just out of interest, I use extended co-routines (by the equally amazing Twisted Oak Studios) in my builds to handle exceptions and return parameters. Would your library integrate with that?
https://www.youtube.com/watch?v=ciDD6Wl-Evk
http://twistedoakstudios.com/blog/Post83_coroutines-more-than-you-want-to-know
Peter - cyberealityGrand ChampionNice work.
- SvenVikingExpert ProtegeI'm using a fair number of coroutines currently, so this sounds great! I'll check it when I have the chance.
- AblazeExplorer
"peterept" wrote:
Hi,
Since no-one has said thank you, I'll just take a moment to say "Thank you!". It's this kind of work that is a key contributor to everyone producing better and more consistent Unity experiences.
Just out of interest, I use extended co-routines (by the equally amazing Twisted Oak Studios) in my builds to handle exceptions and return parameters. Would your library integrate with that?
https://www.youtube.com/watch?v=ciDD6Wl-Evk
http://twistedoakstudios.com/blog/Post83_coroutines-more-than-you-want-to-know
Peter
Thanks Peter :)
The key thing that makes MEC run without per-frame alloc is that it doesn't use a generic object in the return value like Unity's coroutines do. It's the type casting of this yield return <object> that causes the heap allocation. However, that does make it so you can't hook additional types into the return value.
As for exceptions, the default behavior is to output them to the console. However, the file isn't compiled to a dll or anything, so you can find the three try-catch blocks in the script and change them so they point to your custom error handler.
So, no on the returning values and yes on the custom exception handling. - SvenVikingExpert ProtegeWhen following the instructions in the PDF, changing "yield return null" to "yield return 0f" etc. and attempting to use:
private IEnumerator<float> ListenForAudioStop(AudioSource src)
I receive the errors:error CS0308: The non-generic type `System.Collections.IEnumerator' cannot be used with the type arguments
error CS1624: The body of `...ListenForAudioStop(AudioSource)' cannot be an iterator block because `IEnumerator<float>' is not an iterator interface type - SvenVikingExpert ProtegeThanks! That fixed it. Unimportant, but the documentation says to use Timing.StartCoroutine(), while the method name is Timing.StartUpdateCoroutine().
By the way, the methods don't return a Coroutine object. I'm currently saving my coroutine reference and aborting it with StopCoroutine() under some circumstances. Is there any way to do something like that using MEC?
Interestingly, the profiler will only show GC Alloc for Coroutines with Deep Profile *disabled*, for some reason. Strange.
(On a separate but related subject, even in a completely empty project the profiler shows Total GC Alloc rising gradually from 7.6MB to 10.4MB and getting garbage collected every couple of seconds. The only case of GC Alloc listed in the profiler is 32B per frame for GameView.GetMainGameViewRenderRect(), but that doesn't add up so there must be something else not shown.) - vidonmeHonored GuestThanks! Is it always more efficient than Unity's or just in certain cases?
- AblazeExplorer@SvenViking There is a KillCoroutine function. I just submitted an update that will allow you to either kill a coroutine by passing in the type (in which case it will kill the first found instance of that named function) or you can pass in the coroutine's instance you want to kill.
That is really interesting that deep profiler doesn't show the GC alloc. You could be seeing all that untracked alloc because the profiler itself creates a lot of overhead (but obviously only when it's running.)
@vidonme It's always more memory efficient. They should be more processor efficient as well, but I haven't had a chance to profile them side by side yet.
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device