Whats the difference between Transform and UnityEngine.Transform?

I was checking our profiles, and noticed these:

7964526--1021014--upload_2022-3-15_11-4-50.png

7964526--1021023--upload_2022-3-15_11-5-46.png

7964526--1021017--upload_2022-3-15_11-5-21.png
7964526--1021020--upload_2022-3-15_11-5-33.png

I was just wondering, i highly doubt we have custom classes with the same names, so they must be from Unity. Why are there two Transforms and GameObjects?

7964526--1021023--upload_2022-3-15_11-5-46.png

1 Like

I suspect the UnityEngine ones are the C# class and the others are the C++ objects, which could explain the difference in size (most data is stored in the C++ types).

1 Like

Yup. A C# Transform has 3 fields, all inherited from Object. Assuming a 32 bit system, 50771 * 3 * 4 bytes = ~1.2 mb, so that’s very sensible.

The 26 mb for the 70k c++ transforms seems insane, though - that’s almost 100 floats worth of memory for each transform! I assumed it only needed a matrix4x4 and a parent pointer of some sort. It could be that it’s the size reserved for transform data?

Hello,
It’s been sorta answered all ready but yes: That’s the Native “Unity” Object (no name space, basically everything that on the Managed Side would inherit from UnityEngine.Object) and the Managed Shell Object (also referred to as Managed Wrapper or when leaked while the native Object is Destroyed: Leaked Empty Shell or Fake Null).

Also, Yes there is a GameObject Type object and a Transform component. The Scene Hierarchy is technically structured by Transforms, not by GameObjects. The Size of the GameObject Type is mostly informed by Serialization data and not by the components, which are all listed out on their own in the Memory Profiler UI (albeit referenced by the the GameObject.

Yes we know this is confusing but the package so far has just been showing you the data the way the data is structured. While that is technically correct, it is not necessarily in a way that is intuitive to a Unity User that hasn’t gone deep on the Native backend and how our bindings / Managed Shell ↔ Native Object ↔ Native Root ↔ Native Allocation mapping is working.

We are slowly adding extra processing to the data and are restructuring the UI to something clearer and more intuitive. The Details Side panel has already started that transition. It shows clearly if an Object is Native, Managed or if we have combined the Native Object with the Managed Shell to show a richer version of that object. We want to similarly merge GameObjects with their components, and allow to e.g. sort them by the SceneHierarchy so that the data looks a bit more sensible and is more intuitive to grasp.

The old tables and the TreeMap are not getting that treatment though. They are now very much put out to pasture and all focus is on replacing them with better UI TK tables in the versions to come :slight_smile:

The more complex the transform Hierarchy, the more memory they need to store. I.e. Transforms store a list to all children.

3 Likes

Oh yeah and: you only need a Managed Wrapper to a native object, if something from C# wants to access it. On first access the Shell is created and retained. This is why you are seeing less Managed Shells than Native Objects, because some of them are just not needed (so far) for your C# Code

1 Like

I cant show you with screenshots, but its really helpful to open them up. We have one object thats basically the root of the scene, and this takes up 50% of the transform size. This is only the m_children property being huge, the profiler makes this very obvious.

2 Likes

Yeah, those root level transforms are terrible for performance.

  • They take up a lot of memory
  • They make it impossible for separate branches of the scene hierarchy to be updated independently from each other.

So I’m glad the memory Profiler is helping in pointing them out.

If somebody would go nag whatever team’s supposed to be working on hierarchy folders to get on with it, we wouldn’t keep using root level transforms.

Before nested prefabs, we had workflows where generally every single level had a single root object that everything was required to be under, for organizational purposes.

I hear you, believe me.

Just stating how it is for the time being. :confused: