Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Memory leak during creation of an entity prefab

Discussion in 'Entity Component System' started by howaboutno000, Dec 8, 2020.

  1. howaboutno000

    howaboutno000

    Joined:
    Nov 13, 2020
    Posts:
    20
    I'm trying to learn DOTS from an online tutorial.

    The intent is to take in GameObject prefab, turn it into entity prefab and then create any needed entities from that prefab. It ends with three same errors: "A Native Collection has not been disposed, resulting in a memory leak. Enable Full StackTraces to get more details.", nothing else, double-clicking does nothing. Googling it shows that it happens to people in relation to analytics, but I have none, its turned off.

    If executeOnStart is false, this error doesn't happen. This script is attached to the GameObject:

    Code (CSharp):
    1.  
    2. public class PrefabSpawner : MonoBehaviour
    3. {
    4.  
    5.     public bool executeOnStart;
    6.     [SerializeField] GameObject gameObjectPrefab; // fails on anything, null, standard unity shape or a model.
    7.     Entity entityPrefab;
    8.     World defaultWorld;
    9.     EntityManager entityManager;
    10.  
    11.     void Start()
    12.     {
    13.         defaultWorld = World.DefaultGameObjectInjectionWorld;
    14.         entityManager = defaultWorld.EntityManager;
    15.         if (executeOnStart) DoIt();
    16.     }
    17.  
    18.     void DoIt()
    19.     {
    20.         EntityArchetype archetype = entityManager.CreateArchetype(
    21.             typeof(Translation),
    22.             typeof(Rotation),
    23.             typeof(RenderMesh),
    24.             typeof(RenderBounds),
    25.             typeof(LocalToWorld)
    26.         );
    27.          
    28.         var settings = GameObjectConversionSettings.FromWorld(defaultWorld, new BlobAssetStore());
    29.         entityPrefab = GameObjectConversionUtility.ConvertGameObjectHierarchy(gameObjectPrefab, settings);
    30.  
    31.         // Create 100 copies
    32.         for (var i = 0; i < 100; i++)
    33.         {
    34.             Entity myEntity = entityManager.Instantiate(entityPrefab);
    35.             entityManager.SetComponentData(myEntity, new Translation
    36.             {
    37.                 Value = new float3(5, 10, 15)
    38.             });
    39.         }
    40.     }
    41. }
     
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,580
    Have you any other system in your project?
    It looks like you have NativeArray somewhere, which is not disposed.
     
    Lukas_Kastern likes this.
  3. Lukas_Kastern

    Lukas_Kastern

    Joined:
    Aug 31, 2018
    Posts:
    97
    You have to keep a reference to the BlobAssetStore that you create in line 28.
    Otherwise, the native collections inside it will start complaining when the asset store gets out of scope.
     
    Antypodish and howaboutno000 like this.
  4. howaboutno000

    howaboutno000

    Joined:
    Nov 13, 2020
    Posts:
    20
    I don't. I checked project for NativeArray, never happens, not once in my entire project. There are references in the package, but not in the Asset folder.

    That solved it perfectly. I created a field, and then created new instance before using it. But why? Is this a bug or am I just stupid? Shouldn't you keep the reference regardless?

    Edit: Nevermind, now when I exit play mode I get the same three messages. What to do now?
     
    Lukas_Kastern likes this.
  5. Lukas_Kastern

    Lukas_Kastern

    Joined:
    Aug 31, 2018
    Posts:
    97
    You have to dispose of the asset store somewhere, that blob asset store should be coupled to the lifetime of the world tho.

    The easier way is to just grab the BlobAssetStore which the ConvertToEntitySystem uses. You can get a reference to it by calling
    Code (CSharp):
    1. defaultWorld.GetExistingSystem<ConvertToEntitySystem>().BlobAssetStore
     
    howaboutno000 likes this.