Search code examples
c#unity-game-enginemonomarshallingunmanaged-memory

Under which conditions Marshal.SizeOf allocates on the heap?


So I have very weird tracing data from dotTrace: enter image description here

Here is the struct:

public struct TargetStruct : SomeInterface
{
    private RigidTransform rt;
    public RoundBounds rb;
    public int Start;
    public Bool IsEnabled;
    public TypeEnum TheType;
}
//
// Nested types
//
public struct RoundBounds : SomeInterface
{
    public float3 Center;
    public float Radius;
    public float RadiusSq;
}
public struct Bool : IEquatable<Bool>, SomeInterface
{
    [MarshalAs(UnmanagedType.I1)]
    private bool value;
}
public enum TypeEnum : byte
{
    None,
    Type1,
    Type1
}
public struct RigidTransform
{
    public quaternion rot;
    public float3 pos;
    public static readonly RigidTransform identity = new RigidTransform(new quaternion(0f, 0f, 0f, 1f), new float3(0f, 0f, 0f));
}

This runs under Unity's mono 2019.4.12-mbe, if it is relevant, Unity generates project targeting 4.7.1. Struct is being passed down to SizeOf via generic methods with constraints where T: struct, though this should be irrelevant.

Here is IL of mono's mscorlib Marshal.SizeOf<T>: enter image description here Call is forwarded to external SizeOf(Type t);

What can possible cause heap allocations? My only assumption is boxing, but I cant see any boxing here. GetType() should not allocate


Solution

  • The link you refer to regarding the allocation behavior of GetType() says that it doesn't allocate a new instance every time, it does not say it doesn't allocate at all.

    The first time you call GetType() on an object of a particular type will result in the allocation of a new RuntimeType instance to represent the type, but it's a one-off allocation and subsequent GetType() calls on objects of that type will return the existing instance.