Search Unity

Persistant Allocation of TransformAccessArray

Discussion in 'Entity Component System' started by Micz84, Jun 21, 2018.

  1. Micz84

    Micz84

    Joined:
    Jul 21, 2012
    Posts:
    451
    I have a TranformAccessArray that is allocated on start with a capacity of 2000, and I add and remove Transforms from it. I have an IJobParalelforTransform that scales transform based on distance from the camera.

    Code (CSharp):
    1. struct SizeUpdateJob : IJobParallelForTransform
    2.         {
    3.             [ReadOnly]
    4.             public Vector3 camera;
    5.  
    6.             [ReadOnly]
    7.             public float _SizeChangeStartDistance;
    8.             [ReadOnly]
    9.             public float _SizeChangeMaxDistance;
    10.             [ReadOnly]
    11.             public float _MaxSize;
    12.  
    13.  
    14.             public void Execute(int i, TransformAccess transform)
    15.             {
    16.              
    17.                 var distanceFromCamera = Vector3.Distance(transform.position, camera);
    18.                
    19.  
    20.                 Vector3 size = Vector3.one;
    21.              
    22.                 if (distanceFromCamera > _SizeChangeMaxDistance)
    23.                     size = new Vector3(_MaxSize, _MaxSize, _MaxSize);
    24.                 else
    25.                 {
    26.                     var sizeFactor = 1 + (_MaxSize - 1) * (distanceFromCamera - _SizeChangeStartDistance) / (_SizeChangeMaxDistance - _SizeChangeStartDistance);
    27.                     size = new Vector3(sizeFactor, sizeFactor, sizeFactor);
    28.                 }
    29.  
    30.                 transform.localScale = size;
    31. }
    32.              
    33.             }
    This code is running every frame. I dispose this TransformAccessArray in OnDestroy() method. But still, I get an error:
    A Native Collection has not been disposed, resulting in a memory leak. It was allocated at ...
     
    Last edited: Jun 21, 2018
  2. avvie

    avvie

    Joined:
    Jan 26, 2014
    Posts:
    74
    yeah, had the same thing. Well in editor after each compile you can disable the checks. It will run fine. In a build, if i am not mistaken, the error checking is disabled.
    As long as you know that its safe for sure then its all good in this concept. There might be an attribute to silence the compiler but i havent found it yet
     
  3. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    I failed to pre-instantiate manual TAA stored as a system's field on system start as well. The only way it works without error is to instantiate in OnUpdate -> Send it to job and schedule the job -> immediately dispose at the final line of OnUpdate. I thought the dispose comes early it might make the job unable to use TAA but turns out it still works in the job. (blog)

    That error message shows when a reference count of any native container becomes 0 while you are not disposing. How can that be when I am holding on to the variable myself on system start?

    So I suspect IJobParallelTransform is decreasing that reference count manually. Maybe it is a kind of hack for it to work with injected TransformAccessArray so you don't have to dispose them yourself? Whatever the reason is the proper way to use handmade TAA then seems to be the instantiating every frame and immediately disposing way I described or better just not create TAA manually and try to make it come from the inject if possible.