how to fix memory leak?

This code spits out "A Native Collection has not been disposed, resulting in a memory leak. It was allocated at "… at each “new NativeArray” which is weird given that those are disposed once the jobs are complete.

    int currentIndex;
    public NativeArray<float> influences, influencesBuffer;
    public NativeArray<Vector2> flowVectors;
    JobHandle handleInfluence, handleFlowVector;
    NativeArray<float> emitterGrid;
    void Update()
    {
        if (handleFlowVector.IsCompleted)
        {
            //setup the emittergrid
            emitterGrid = new NativeArray<float>(obstacleZero, Allocator.Persistent);
            foreach (var e in settings[currentIndex].emitters)
            {
                var pos = World2Grid(e.transform.position);
                if (pos.x >= 0 && pos.x < size.x && pos.y >= 0 && pos.y < size.y)
                    emitterGrid[pos.x + pos.y * size.x] += e.value;
            }

            // launching current influence job
            influences = new NativeArray<float>(size.x * size.y, Allocator.Persistent);
            influencesBuffer = new NativeArray<float>(size.x * size.y, Allocator.Persistent);
            ComputeInfluenceJob jobInfluences = new ComputeInfluenceJob()
            {
                decay = settings[currentIndex].decay,
                height = size.y,
                influencesOut = influences,
                influencesBuffer = influencesBuffer,
                momentum = settings[currentIndex].momentum,
                obstacleGrid = new NativeArray<float>( obstacleValues, Allocator.TempJob),
                emitterGrid = emitterGrid,
                width = size.x
            };
            handleInfluence = jobInfluences.Schedule(size.x * size.y, batchSize);

            // launching computation of vector fields
            flowVectors = new NativeArray<Vector2>(size.x * size.y, Allocator.Persistent);
            ComputeFlowVectors jobFlow = new ComputeFlowVectors()
            {
                flowVectorsOut = flowVectors,
                height = size.y,
                influences = influences,
                width = size.x
            };
            handleFlowVector = jobFlow.Schedule(size.x * size.y, batchSize, handleInfluence);
        }
    }

    void LateUpdate()
    {
        if (handleFlowVector.IsCompleted)
        {
            handleFlowVector.Complete();
            flowVectors.CopyTo( settings[currentIndex].flowVectors);
            output.SetPixels(colors);
            output.Apply();
            //
            flowVectors.Dispose();
            influencesBuffer.Dispose();
            influences.Dispose();
            emitterGrid.Dispose();
            //
            currentIndex++;
            currentIndex %= settings.Length;
        }
    }

what about obstacleGrid in ComputeInfluenceJob jobInfluences you make array inside a job but never dispose it

that one doesn’t spit out an error, tempjob did the trick

Unrelated to your issue, but I wonder…

Is this is the proper use of IsCompleted and Complete()? I thought IsCompleted returns true once the job completed, thus no need to actually call Complete()?

Using this in the following way makes more sense to me

if (!handleFlowVector.IsCompleted)
    handleFlowVector.Complete();

// Code that expects job completed goes here
2 Likes

then try to move

influencesBuffer.Dispose();
influences.Dispose();
emitterGrid.Dispose();

to end of your update() function