What happened if I allocate memory in job and dispose it out of the job?

I create a thread container just like an read only UnsafeList witch element is NativeList(UnsafeList<NativeList>).
When you create one, you create serval NativeList for every single thread.

        [NativeSetThreadIndex]
        private int threadIndex;
        private UnsafeList<NativeList<T>> threadList;
        private Allocator _containerAllocator;
        
        public ThreadList(Allocator allocator,Allocator containerAllocator = Allocator.Temp)
        {
            threadList = new UnsafeList<NativeList<T>>(JobsUtility.ThreadIndexCount, allocator);
            for (int i = 0; i < JobsUtility.ThreadIndexCount; i++)
            {
                threadList.Add(default);
            }
            threadIndex = 0;
            _containerAllocator = containerAllocator;
        }

When you need a NativeList, call

        public ref NativeList<T> CreateListRef(int capacity)
        {
            ref var list = ref threadList.ElementAt(threadIndex);
            if (!list.IsCreated)
            {
                list = new NativeList<T>(capacity, _containerAllocator);
                threadList[threadIndex] = list;
            }
            else if (list.Capacity < capacity)
            {
                list.Capacity = capacity;
            }

            list.Clear();
            return ref list;
        }

. therefore every thread use there own single NativeList.

I use it in some different way.
1、Use it like container pool. Create in job with temp allocator in the first call, when it is created already, just clear. It’s temp allocator so I don’t dispose it in job. Just dispose threadList out of job which allocated by tempjob allocator.
2、Use it like parallel collecter. Create in job with temp allocator in the first call, don’t clear in next call. Collect all data in every thread out of job. It’s thread safe because every thread has there own list. However, I need read data out of job, so I need create NativeList with tempjob allocator and dispose them when I dispose threadList.

there’s some question:
1、When I allocate temp NativeList in job and Dispose it out of the job, It throw an exciption “allocator handle is not valid”. I correct it by if (_containerAllocator is not (Allocator.Temp or Allocator.None or Allocator.Invalid)). But I still don’t know why and what happend.
2、Is it safe when a allocate tempJob memory in job and dispose it out of job?

1 Like

Maybe you better use Persistent outside the job and manage all the allocation manually. After all, a pool of memory is persistent compared to temp or tempjob. Using unmanaged memory | Collections | 1.1.0

The manual also says:

Temp allocations are only safe to use within the thread where they were allocated. So while Temp allocations can be made within a job, main thread Temp allocations cannot be passed into a job . For example, a NativeArray that’s Temp allocated in the main thread cannot be passed into a job.

I would assume it’s also the other way round since the job is just gone and any temp allocations are gone with it unless they are persistent ones on the main thread.

1 Like

thank you and I noticed this doc. It resolved my question 1, but I still want to know if it’s safe that I allocate tempJob memory in job and dispose it out of job. Because you can’t do it with internal containers and there is no doc mentioned it.

TempJob has the same rules as Persistent with regards to being able to allocate and dispose in separate jobs or a combination of jobs and main thread. The only difference is that TempJob is intended to be used for short-lived allocations (less than 4 frames) and uses pooled memory buckets.

With all that said, if you aren’t familiar with RewindableAllocator and DoubleRewindableAllocator, I suggest looking into those, as those are usually a better alternative to TempJob.