Permanent NativeArray causes 'not disposed' error

I’m using the jobs system to generate terrain data and run marching cubes. Everything is running fine until I suddenly get this error after the game is running for a minute A Native Collection has not been disposed, resulting in a memory leak.

The error is generated from the densityMap allocated here:

public TerrainChunk (int size, float voxelSize, MeshObject meshObject) {
    this.meshObject = meshObject;
    this.voxelSize = voxelSize;
    this.size = size;

    densityMap = new NativeArray<float>((size + 1).Pow(3), Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
    vertexCounter = new Counter(Allocator.Persistent);
}

I make sure to Dispose the native collection when I am done with it (when the game quits)

public void Dispose () {
    CompleteRunningJobs();
 
    densityMap.Dispose();
}

The system still gives me an error a little while after a job using the collection is completed. I understand that I didn’t dispose of the collection after the job completed, but that is kind of the point. It should stay alive as long as the terrain chunk is alive. That way I can reuse the collection when the user modifies the terrain.

The full source code is available here GitHub - KuroiRoy/Fast-Unity-Marching-Cubes: Marching Cubes with destructible terrain made in Unity utilizing latest Unity features, like collider baking on separate threads and setting raw mesh buffers.

Is there a way to avoid this error? Do I have to keep my data in a managed array until I run a new job on it?

Is it because I’m not keeping my native collection in a monobehaviour?

Okay, to solve this it seems like you are forced to keep the native collections in a MonoBehaviour. Why does it have to be like that though? Is it because then the native collection is in a Unity managed Object?

Not having this issue, and do not allocate anything from MonoBehaviour. All my allocations are from Systembase. Couple of thoughts:
(1) You might want to dispose by overriding the SystemBase function OnDestroy:

 protected override void OnDestroy()
    {
        base.OnDestroy();
        if (readyMaps.IsCreated) readyMaps.Dispose();
        if (filteredEntities.IsCreated) filteredEntities.Dispose();
    }

(2) do you dispose your vertexCounter ?
(3) how do you call TerrainChunk? Could it be you allocate say 10 NativeArrays, but dipose only 9?

Hey @Fribur thanks for your reply.

(1) I’m not using entities for my chunk objects. I might try it out though since I now have a gameobject for every chunk anyway.
My problem is with the fact that I seemingly can’t store the native array in a class that does not inherit from monobehaviour. Since the chunk only reference a gameobject for mesh rendering. The rest of the logic is separate.

(2) I don’t think I did. It wasn’t giving me any errors but thanks for pointing it out.

(3) Any native arrays are inside the chunk and the chunks are stored in a pool when not in use. So any native array inside a chunk should stay alive until I quit the application.