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

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?

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.

1 Like

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.

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.

Though if you spawn new objects without thought you have created a memory leak.

Pooling can mitigate that

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.

1 Like

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.

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.

1 Like

Are GameObject not GC collected when destroyed and no longer referenced ?
If they stay on scene than this is a serious memory leak.

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?

I found these:

talking about the garbage collector flavor used by Unity.
They’re old info but I’m asking if somebody knows if the information is up-to-date for Unity 2019/2020.

Another point: AFAIK Mono framework uses a compacting GC so it’s a little contradiction with the articles.

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.

2 Likes

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!

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.

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()).

6 Likes

So my guesswork above was on point, nice :slight_smile: