Search Unity

Is it possible to pin GameObjects in memory so GC couldn't relocate them?

Discussion in 'General Discussion' started by AndreiMarian, Mar 29, 2021.

  1. AndreiMarian

    AndreiMarian

    Joined:
    Jun 9, 2015
    Posts:
    77
    I know GC moves variables around in memory during compacting phase. I assume GameObjects are no exception. So is there a way to ensure the same memory address for a GameObject throughout the application runtime?
     
  2. unity-freestyle

    unity-freestyle

    Joined:
    Aug 26, 2015
    Posts:
    45
    I believe that Unity Objects actually are an exception due to the C++ layer, so this should not be a problem.

    But I'm not 100% sure about this.
     
    Joe-Censored likes this.
  3. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,572
    I believe GameObjects are not collected by GarbageCollecotr in the first place.

    They stay in the scene even if you do not reference them from your code.
     
  4. AndreiMarian

    AndreiMarian

    Joined:
    Jun 9, 2015
    Posts:
    77
    I dared to hope for game objects to be an exception. 2 opinions in this direction mean a lot. If I find more on this I'll write in here. Thanks guys.
     
  5. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    Though if you spawn new objects without thought you have created a memory leak.

    Pooling can mitigate that
     
  6. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,572
    Technically, even if GameObjects weren't an exception and were normal C# objects, they wouldn't die automatically.
    Because they would still be referenced by the Scene they're part of. So even if you let go of a reference, another one would still exist in the scene, and would keep the object alive.
     
    Joe-Censored likes this.
  7. AndreiMarian

    AndreiMarian

    Joined:
    Jun 9, 2015
    Posts:
    77
    Now that I'm thinking about it, doesn't this mean memory leak? I googled "unity gameobject garbage collector" but found nothing special on GameObject. If you or anybody else finds anything please, post a link.

    And there are 2 related but distinct matters:
    1. collecting GameObject's as in freeing their memory once they're not referenced anymore. This is something out of users reach, handled by Unity.
    2. relocating or not GameObject's in their life (be it infinite). This I'm hoping to be in users' grasp.
     
  8. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,572
    No.
    Game Objects exist as a part of the scene (except when they're prefabs).

    Loading the scene, kills previous objects in it. (unless they have a DontDestroyOnLoad flag set)


    No, you can kill any GameObject with Destroy(), referenced or not.

    And if you want to emulate GC behavior, create a class derived from IDisposable with a reference to a gameobject, and have it kill the gameobject within Dispose.

    Personally, I wouldn't bother with that.
     
    Joe-Censored likes this.
  9. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,074
    Are GameObject not GC collected when destroyed and no longer referenced ?
    If they stay on scene than this is a serious memory leak.
     
  10. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    They stay in the scene. In fact I dont think gameobjects allocate the managed heap. Only their components if not native code. edit: Well the gameobject reference must allocate offcourse, but I wonder if one is created if managed code havent asked for it?
     
  11. AndreiMarian

    AndreiMarian

    Joined:
    Jun 9, 2015
    Posts:
    77
  12. billykater

    billykater

    Joined:
    Mar 12, 2011
    Posts:
    329
    The most up to date information I remember from various threads about moving to .net core and past hackweeks (somewhere in the 2017-2019 range) posts is that most of unity's native side assumes that things never move which is why the transition to newer mono/.net versions would take a lot of effort that just now seems to be ramping up.

    Mono has historically used the boehm gc before developing sgen. That is why mono now uses a compacting gc but unity is still using boehm due to historical reasons.

    Currently it is likely that they are still on the incremental version of boehm (try to find the beta thread for incremental garbage collection somewhere in this forum). Thus currently objects might never be moved but that information might be out of date without trying to verify it.

    To answer your initial question: To make sure that a managed object stays where it is you can use GCHandle but I would caution against using it extensively. As I haven't seen what your use case for them would be I can't be more specific.
     
    Joe-Censored and NotaNaN like this.
  13. stain2319

    stain2319

    Joined:
    Mar 2, 2020
    Posts:
    417
    This thread is way beyond anything I'm likely to need to worry about but I'm curious as to why one would want or need to do this... Performance optimization? It seems like trying to out-think the garbage collector which is normally way above my pay grade!
     
  14. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Even if this is the case today, utilizing this in your project should get the same caution as taking advantage of any other undocumented behavior of Unity. That is, if Unity isn't making any explicit guarantees about the behavior, don't be surprised when that behavior changes in future versions of Unity without any notice.
     
  15. superpig

    superpig

    Drink more water! Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,659
    Types derived from UnityEngine.Object have two pieces: a C++ part and a C# 'wrapper'. The C++ part holds a reference to the C# part, though for many types this is populated lazily, so e.g. we don't create C# wrappers for Transform components that you never access from C# code.

    The C++ part is destroyed using Object.Destroy() or Object.DestroyImmediate, or by operations that explicitly destroy objects (such as unloading a scene), or by what we call the 'Asset GC' (which is a separate garbage collector to the C# one, and can be manually invoked by calling Resources.UnloadUnusedAssets()).
     
    neginfinity, Ryiah, Socrates and 3 others like this.
  16. MDADigital

    MDADigital

    Joined:
    Apr 18, 2020
    Posts:
    2,198
    So my guesswork above was on point, nice :)