This may vary depending on the version your are using. In Unity 6 (Unity.Collections 2.4.2) i cannot see FixedList per-se, but its variants (FixedList32Bytes, 64, 128…)
For what i can see, a FixedListXXBytes, “simulates” a list (thus it is “resizable” in added elements terms, but not on memory terms) by allowing to “Add” and “Remove” elements, but its real underlying byte size is always the same (stipulated by your XXBytes overload), and will throw if you add elements beyond its capacity.
A NativeArray<T> is not “resizable”, it is allocated once upon being created, and then you can just set items on it. If you ever wanted to change its size, you would dispose of it and create a new one.
So, if your array does not change size often, a NativeArray seems the better choice.
When the docs say it is “safe” they mean that you will get warnings/errors if , for example, 2 concurrent jobs want to read & write at the same time on the same NativeArray, which would be unsupported, or if you forget to Dispose a collection (thus getting a memory leak)
PD: Recently i read this post, where the usage of an UnsafeList might be very usefull. In that particular case, the “safe” restrictions caused the OP not to be able to have nested containers. This is unsupported on “Safe” collection variants because Unity cannot implement “safe” handling for nested collections. In that case, if you know what you are doing, you can use a “Unsafe” variant of a collection to skip the restrictions (you wont get errors, so you could use them in cases where a Safe variant would throw an exception), but at the cost of not getting exceptions or warnings if you dont use them correctly
Afaik fixedlists arent safe for use in jobs directly(I assume it would compile and not blow up but the results of what you do would just be wildly incorrect), but you can use them inside of native collections as well as component/buffers on entities. Placing native collections on components is possible but not without restrictions, and only at runtime.
Im sure someone else can fill in the finer details.
FixedList* is generally stack allocated and it is immutable, meaning a few things:
Since it’s immutable, changes you make to it in a function are not propagated back unless you pass it with ref or return a copy of it.
Unless there is some magic happening, jobs only receive a copy of the data and can’t write data to your stack. (maybe with some fancy unsafe ref things?)
It has a fixed size, hence the name “fixed”, so if your data is large, it will overflow the list.
Depending on your stack size, you can cause a stack overflow if you have many of these.
Native Containers, including NativeArray, have data that can be allocated dynamically. This usually means they’re stored on the heap. That’s why they need an allocator to construct them, and why they need to be disposed.