The drawback to the safety system’s process of copying data is that it also isolates the results of a job within each copy. To overcome this limitation you need to store the results in a type of shared memory called NativeContainer.
A NativeContainer
is a managed value type that provides a relatively safe C# wrapper for native memory. It contains a pointer to an unmanaged allocation. When used with the Unity C# Job System, a NativeContainer
allows a job to access data shared with the main thread rather than working with a copy.
Unity ships with a NativeContainer
called NativeArray. You can also manipulate a NativeArray
with NativeSlice to get a subset of the NativeArray
from a particular position to a certain length.
Note: The Entity Component System (ECS) package extends the Unity.Collections
namespace to include other types of NativeContainer
:
NativeList
- a resizable NativeArray
.NativeHashMap
- key and value pairs.NativeMultiHashMap
- multiple values per key.NativeQueue
- a first in, first out (FIFO) queue.The safety system is built into all NativeContainer
types. It tracks what is reading and writing to any NativeContainer
.
Note: All safety checks on NativeContainer
types (such as out of bounds checks, deallocation checks, and race condition checks) are only available in the Unity Editor and Play Mode.
Part of this safety system is the DisposeSentinel and AtomicSafetyHandle. The DisposeSentinel
detects memory leaks and gives you an error if you have not correctly freed your memory. Triggering the memory leak error happens long after the leak occurred.
Use the AtomicSafetyHandle
to transfer ownership of a NativeContainer
in code. For example, if two scheduled jobs are writing to the same NativeArray
, the safety system throws an exception with a clear error message that explains why and how to solve the problem. The safety system throws this exception when you schedule the offending job.
In this case, you can schedule a job with a dependency
See in Glossary. The first job can write to the NativeContainer
, and once it has finished executing, the next job can then safely read and write to that same NativeContainer
. The read and write restrictions also apply when accessing data from the main thread. The safety system does allow multiple jobs to read from the same data in parallel.
By default, when a job has access to a NativeContainer
, it has both read and write access. This configuration can slow performance. The C# Job System does not allow you to schedule a job that has write access to a NativeContainer
at the same time as another job that is writing to it.
If a job does not need to write to a NativeContainer
, mark the NativeContainer
with the [ReadOnly]
attribute, like so:
[ReadOnly]
public NativeArray<int> input;
In the above example, you can execute the job at the same time as other jobs that also have read-only access to the first NativeArray
.
Note: There is no protection against accessing static data from within a job. Accessing static data circumvents all safety systems and can crash Unity. For more information, see C# Job System tips and troubleshooting.
When creating a NativeContainer
, you must specify the type of memory allocation you need. The allocation type depends on the length of time the job runs. This way you can tailor the allocation to get the best performance possible in each situation.
There are three Allocator types for NativeContainer
memory allocation and release. You need to specify the appropriate one when instantiating your NativeContainer
.
NativeContainer
allocations using Temp
to jobs. You also need to call the Dispose
method before you return from the method call (such as MonoBehaviour.Update, or any other callback from native to managed code).Temp
but is faster than Persistent
. It is for allocations within a lifespan of four frames and is thread-safe. If you don’t Dispose
of it within four frames, the console prints a warning, generated from the native code. Most small jobs use this NativeContainer
allocation type.NativeContainer
allocation type. You should not use Persistent
where performance is essential.For example:
NativeArray<float> result = new NativeArray<float>(1, Allocator.TempJob);
Note: The number 1 in the example above indicates the size of the NativeArray
. In this case, it has only one array element (as it only stores one piece of data in result
).
2018–06–15 Page published
C# Job System exposed in 2018.1 NewIn20181
When you visit any website, it may store or retrieve information on your browser, mostly in the form of cookies. This information might be about you, your preferences or your device and is mostly used to make the site work as you expect it to. The information does not usually directly identify you, but it can give you a more personalized web experience. Because we respect your right to privacy, you can choose not to allow some types of cookies. Click on the different category headings to find out more and change our default settings. However, blocking some types of cookies may impact your experience of the site and the services we are able to offer.
More information
These cookies enable the website to provide enhanced functionality and personalisation. They may be set by us or by third party providers whose services we have added to our pages. If you do not allow these cookies then some or all of these services may not function properly.
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us to know which pages are the most and least popular and see how visitors move around the site. All information these cookies collect is aggregated and therefore anonymous. If you do not allow these cookies we will not know when you have visited our site, and will not be able to monitor its performance.
These cookies may be set through our site by our advertising partners. They may be used by those companies to build a profile of your interests and show you relevant adverts on other sites. They do not store directly personal information, but are based on uniquely identifying your browser and internet device. If you do not allow these cookies, you will experience less targeted advertising. Some 3rd party video providers do not allow video views without targeting cookies. If you are experiencing difficulty viewing a video, you will need to set your cookie preferences for targeting to yes if you wish to view videos from these providers. Unity does not control this.
These cookies are necessary for the website to function and cannot be switched off in our systems. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms. You can set your browser to block or alert you about these cookies, but some parts of the site will not then work. These cookies do not store any personally identifiable information.