Hi,
I was wondering if someone used the IDisposable interface in a Unity Game context ever, in order to ease the work of the Garbage collector.
I am assuming that a class that uses GameObject is seen as a class that contains unmanaged code from the GC standpoint.
Any opinion on this? I know that is low level perf optimization topic there, but I am sure some optimization whores looked at this before.
basically right and not right
the disposal is managed by unity and through you by calling Destroy / DestroyImmediate on it.
but the GC will not jump in on its own.
In unity 3 there is an asset manager in addition behind the scene that will clean stuff thats not referenced by unity classes
I am trying to ease the work of the GC actually.
So the strategies are as follows according to my readings:
1-Do not allocate : Damn the code will be ugly, but that s life
2-Set local vars to null when they are not needed anymore: ??? First time I read something like that. Is that really supposed to help the Mono GC? Can anyone confirm? Some ppl say it will be worse.
3- trigger Dispose for classes that contain “unmanaged code”: No real opnion on this yet
If you want to ease the work of the GC, use Pooling instead of create - destroy patterns 
but keep in mind that this only makes sense for whole prefabs, cause the handling is the same for game objects, behaviours and assets in general if they are removed on their own (if you destroy a gameobject, all stuff bound to it like behaviors etc will be destroyed too)
-
would like to see how to do that. instantiate or having it in the scene allocates stuff by default, unity objects aside of gameobject don’t accept “new xxx()” anyway
-
mono gc, yes. For unity it makes no difference because unity holds internal references as mentioned, so you can null it till you go green. If you don’t call Destroy / DestroyImmediate it will go exactly nowhere
-
don’t do that or you risk that the whole thing blows up as unity internally manages them and does the dispose if you request it (destroy / destroyimmediate)
thanks for the reply, that is very useful, but I am not really worried about the Unity Objects Creation/Detruction at the moment.
Here is the reason of all of this: I did some profiling in Unity3 yesterday, and noticed that the GC.Collect() is called very often.
since you replied I wondered: Is this GC.Collect() executing only on Mono objects or Unity + Mono objects?
The strategies I mentioned were for Mono objects only.
Unity 3 behaves differently than Unity 2 (you should put that into the title optimally)
Unity 3 has an automatic manager in the background that will clean out unused assets on its own.
Also, that GC.Collect runs regularily is nothing that uncommon, at least it would be new to me if it were.
it normally just does not have much work to do and thus goes through unseen
I am no pro at unity having just started trying it out but I will express my opinion from a .net perspective. The IDispose pattern should only be used for objects that use unmanaged resources. If you are creating something that is a manged object - most .net objects are, then the GC will always clean them for you at the best time.
Basically the GC spawns a thread to clean all unreferenced objects at certain points. It optimises this for performance so it does so with the least amount of hurt to you.
When an object has the IDisposable interface, ie: it has a finaliser, then that object is NOT cleaned in the GCs collect. Instead each object marked for disposal with a finaliser is placed in a finaliser queue and the GC then spawns a new thread to run all the finalisers on all the finalised objects. This is necessary so that it can ensure, that your cleanup happens first, before it disposes the object.
It does this because by implementing the IDispose interface, you have told it that this must be done first.
After the thread with the finalisers is run, then only, are those objects placed in the garbage queue and they are only cleaned then on the NEXT GC collect. In other words, objects with finalisers stay in memory longer than those without. You only use finalisers when you have to do cleanup of your own, not to speed up the release of resources - Definitely not.
Another problem you have with using IDisposable is that you then have to implement checks throughout the methods and properties of your class to check if it has been disposed already because it could still be in memory when someone tries to call it again and that causes more issues and more performance loss for the extra checks.
Unitys’ Destroy and DestroyImmediate give you clear control on when you want the object disposed. The IDispose of .net does not.