JobHandle.CombineDependencies causing TempJob allocation warnings

We have some jobs we’re running that might take quite a bit of time and we’re ok with them running across many frames. Like doing some stuff during game loading. We were careful to make sure all of our allocations during this time were using Allocator.Persistent but confusingly we’re still seeing TempJob warnings. I’ve narrowed it down and it appears to be if we use JobHandle.CombineDependencies. Is this a bug or by design?

Below is a simple reproduction of the issue. If the jobs are directly dependent on each other (though there’s no reason for them to be) then there isn’t any issues. However, any attempt to combine their dependencies causes the TempJob warnings.

Unity Version: 2020.1.0b13
Jobs Version: 0.2.10-preview.12 (reproduces on 0.2.10-preview.13)

using System.Collections;
using System.Diagnostics;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
using Debug = UnityEngine.Debug;

public class JobHandleCombineDependenciesTempJob : MonoBehaviour
{
    private void Start()
    {
        // TempJob allocation warnings
        StartCoroutine(TestCombineJobsCo());
      
        // TempJob allocation warnings
        // StartCoroutine(TestCombineNativeArrayCo());
      
        // No TempJob allocation warnings!
        // StartCoroutine(TestDirectDependencyCo());
    }
  
    private IEnumerator TestCombineJobsCo()
    {
        // Warnings!
        JobHandle handle = new WaitJob().Schedule();

        handle = JobHandle.CombineDependencies(
            new EmptyJob().Schedule(handle),
            new EmptyJob().Schedule(handle));

        while (!handle.IsCompleted)
        {
            yield return null;
        }
      
        handle.Complete();
      
        Debug.Log("Done!");
    }

    private IEnumerator TestCombineNativeArrayCo()
    {
        // Warnings!
        JobHandle handle = new WaitJob().Schedule();

        NativeArray<JobHandle> handles = new NativeArray<JobHandle>(2, Allocator.Temp);
        handles[0] = new EmptyJob().Schedule(handle);
        handles[1] = new EmptyJob().Schedule(handle);
      
        handle = JobHandle.CombineDependencies(handles);

        handles.Dispose();
      
        while (!handle.IsCompleted)
        {
            yield return null;
        }
      
        handle.Complete();
      
        Debug.Log("Done!");
    }

    private IEnumerator TestDirectDependencyCo()
    {
        // NO Warnings!
        JobHandle handle = new WaitJob().Schedule();

        handle = new EmptyJob().Schedule(handle);
        handle = new EmptyJob().Schedule(handle);
      
        while (!handle.IsCompleted)
        {
            yield return null;
        }
      
        handle.Complete();
      
        Debug.Log("Done!");
    }

    private struct EmptyJob : IJob
    {
        public void Execute()
        {
        }
    }

    private struct WaitJob : IJob
    {
        public void Execute()
        {
            Stopwatch sw = Stopwatch.StartNew();

            while (sw.ElapsedMilliseconds < 3000)
            {
              
            }
        }
    }
}
2 Likes

As far as I know, this was fixed in 2020.1f1 and above.

Still occurring in 2020.1f1

Try updating the Jobs package to the newest version 0.5.0 preview 14

Still reproduces, the Jobs package isn’t actually necessary at all for this.

Is this not reproducing for others?

EDIT: Also reproducing in 2020.1.6f1

You are right, I can reproduce this with your script on 2020.1.3f1 and Jobs 0.5.0 preview 14.
You can create a clean project with this script and use the unity bug reporter to upload your project and the bug description.

1 Like

you are right. JobsHandle.CombineDependency is still using an allocator that warns if memory stays alive for longer than 2 frames. Scheduling jobs has been fixed.

We’ll fix JobsHandle.CombineDependency as well. For now you have to avoid CombineDependency in long running jobs.

3 Likes

Is there a public bug ticket already opened for this I could follow? Or should I create one?

Will the fix for JobHandle.CombineDependencies land during 2020 cycle or we should only expect it in 2021?

The fix is already in our internal merge queue. You can file an issue if you’d like, or I can just reply to this thread when the fix lands so you’ll know what version(s) will have the fix.

I see no technical reason why the fix couldn’t be backported to 2020.1 and 2020.2. I’ll open those backport requests once the fix lands in 2021.

2 Likes

@cort_of_unity Can’t say for others, but backporting to 2020.2 would be incredibly helpful for the project I’m on.

One question regarding this issue. Other than the warning is there any behavioral problem that will occur? Is it leaking in a release build? (We are seeing a good few of these warning but I haven’t seen good evidence of leaks yet).

Also if you wouldn’t mind posting here when it’s merged that would be great too. Excited to see this one on the way to being fixed :slight_smile:

For me, the game usually crashes in the build, if there are too many of these warnings.

This is great, can’t wait the backports, thank you.

The fix landed in 2021.1 this morning. I’ve opened backport requests for 2020.1 and 2020.2 and will reply when they’re resolved.

There should be no behavioral issue with the existing code. The allocator used internally by CombineDependencies() is intended for short-lived data, so it emits this warning if the memory has not been freed after 4 frames. Since long-running jobs are a supported use of the job system, in this specific case the lifetime check is unnecessary and the warning is spurious. We just needed to use a different allocator in this function that behaves identically, but doesn’t check allocation lifetimes or emit this warning. In either case, so long as the combined handle is eventually .Complete()ed, the internal allocation will be safely released and there will be no leak.

That sounds like a separate problem, though I have also seen cases where pathologically excessive logging can contribute to Editor instability. If you have a reproducible project that demonstrates this issue, please pass it along!

2 Likes

Checked Unity 2020.1.12f1, the issue is still here. Is there any news on which version the fix is planned for 2020.1?

1 Like

Checked Unity 2020.1.17f1, the issue is still here.

1 Like