The GUI's GC.collect -- what exactly is it collecting, and when?

Hi there. I'm one of the many folks who is having problems with GC.Collect running from inside one of my GUI functions every quarter second and basically totally destroying my frame rate. This is on a windows build, mind you, not iPhone. it's not like I should be running out of memory here.

I've started optimizing my OnGUI functions -- removing every allocated variable out of OnGUI (and there have been many) up into the top part of my scripts (I'm using javascript) as a list of private variables -- rects and strings, mostly.

the problem is that as I do this, if anything, the problem is getting worse.

so what the hell is going on? what garbage is GC.collect collecting exactly, and why on earth does it think it needs to run a collection every quarter second or so, when my entire GUI section (according to the profiler) is using only 300 kb of memory?

I'd like to know specifically how this functions, so that I can optimize around it...

Adendum question -- I'm using a custom GUIskin with many (130) custom gui styles in a single skin. most of those are for painted bitmaps that we use for buttons. what kind of an effect does this have on the garbage collector? is having such a large GUIskin a bad idea? do the sheer number of bitmaps themselves get collected as well? I'm also calling the styles by name, using a string. I'm assuming that these strings in the gui function are allocations as well and I should move them off, yes?

Disclaimer: without a response from a Unity developer or the source code, the GC and allocations made by the core code will always be a bit of a mystery. So I cannot answer your question about what exactly is being allocated, and why the collections occur more frequently with native GUI.

At present, any time OnGUI is called, it will generate garbage. So, having

void OnGUI()
{
    // Nothing here
}

in your code will cause positive allocation.

Side note: From what I've read, the GC is called much more frequently with recent version of Unity. This is designed to reduce the devastating impact the GC would have on performance if it was reclaiming like 8MB of memory at runtime.

The obvious solution to this problem is to not call OnGUI -- if you are drawing screen-space textures or text, simply place objects with a texture/text component into your scene and manipulate their properties from Update() or another point in the execution loop. Leave the OnGUI stuff (buttons, sliders, checkboxes, etc) for debugging or intro UI where memory and CPU performance is not an important factor.

I know this doesn't answer all your questions, but hope it helps a bit.

having garbage collections take so much time to destroy your framerate on a desktopmachine is totally not supposed to be happening, and means that either you are diong something wrong, or we are doing something wrong. Can you post a project that reproduces this behaviour so we can try to help?

Hi Lucas, VS48 -- good to hear from you guys, thanks.

ugh, I can't post the project that I'm working on here unfortunately.. it's all supposed to be kept hush hush at the moment. I could submit the whole thing as a bug report, i suppose..?? I'm assuming that's all confidential? it's a rather big project. Should i submit the whole thing as a bug?

after reading VS48's post (Thanks man!!) I tried more-or-less moving all OnGUI functions into a single script (so I have one OnGUI function that basically calls a list of externalScript.RenderMyGUI() functions) and that seems to have had a significant positive effect on this problem. i'm still getting performance spikes but things are staying under 30 fps (barely)... most of the time. it still goes to hell once and a while.

also, the problem isn't noticeable in the webplayer, which is good news... So far it's just in the windows editor. I have had reports of terrible framerates in the webplayer, but they've been few and far between and I haven't been able to reproduce them...