Quick answer: Replace any class, string, List, or Dictionary in your job with NativeArray / NativeList / FixedString. Avoid LINQ and boxing. Closures with captures must become explicit struct fields.
Burst compiler shouts BC1006 at your job. Performance still works in Editor (Mono fallback) but ships unBursted. The warning is fixable; you have to give Burst only types it knows how to compile.
The Symptom
Burst Inspector shows your job with a yellow warning triangle and the message “Burst compilation: Managed object cast.” Job runs but at a fraction of expected speed.
What Causes This
Burst compiles a restricted subset of C# — the “HPC#” subset. Anything that allocates on the managed heap is forbidden:
string(immutable but heap-allocated).List<T>,Dictionary<K,V>, any class.- Boxing a value type to
object. - Capturing delegates (closures), even if they look like local lambdas.
- Reflection (
typeof,GetType(), attributes at runtime).
The Fix
Step 1: Replace List with NativeList.
// Before
public class Worker
{
List<Vector3> positions; // managed
}
// After
[BurstCompile]
public struct WorkerJob : IJob
{
NativeList<float3> positions; // unmanaged, Burst-friendly
}
Step 2: Replace string with FixedString.
FixedString32Bytes name = new FixedString32Bytes("Enemy"); // up to 29 UTF-8 chars
FixedString64Bytes name = new FixedString64Bytes("LongerName"); // up to 61
Step 3: No closures. Refactor delegate captures into explicit struct fields:
// Before (capture)
job.SetCallback(() => Process(myData));
// After (struct field)
job.MyData = myData;
job.Run();
Process(job.Result);
Step 4: Avoid boxing. No object o = (object)5; patterns. No Equals on interface types.
Use Burst Inspector
Window → Burst → Burst Inspector. Pick your job. The right pane shows generated assembly. Yellow warnings sit at offending lines. Hover for the BC code and explanation.
Useful: tick “Show Codegen” to see when Burst falls back to managed paths.
Build-Time Enforcement
To turn warnings into errors so a managed allocation can’t merge:
[BurstCompile(CompileSynchronously = true, DisableSafetyChecks = true)]
public struct MyJob : IJob { ... }
Combined with Project Settings → Burst → Treat Warnings As Errors, accidental managed allocations fail the build instead of silently degrading.
Verifying
Profile in a build (development build, Burst enabled). Job time should drop dramatically — often 5–20x — once managed allocations are gone. Burst Inspector should show no yellow.
“Native containers. FixedString. Struct fields, not closures. Burst flies.”
Related Issues
For Deallocate On Job Completion errors, see deallocate errors. For IL2CPP marshaling, see IL2CPP marshaling.
No managed types. Burst sings.