2026/03/10
C# Job System とは
マルチスレッド処理用のシステム
- 通常の Unity コードはメインスレッド上でしか動かないが、Job System を使うことで複数ワーカースレッド上で処理を並列実行できる
- パフォーマンス改善につながる(フレームレートの大幅な向上など)
【Job System なし】
Main Thread:Update → 重い処理(全部ここで実行) → 描画
→ 重い処理が Main Thread をブロック(フレーム落ち発生)
【Job System あり】
Main Thread:Update → Job をスケジュール → 描画
+ Worker Thread 1:重い処理A ─┐
+ Worker Thread 2:重い処理B ─┤ → 並列実行
+ Worker Thread 3:重い処理C ─┘
→ 重い処理から Main Thread が解放される(フレーム落ち回避)
Job System / Burst の関係
組み合わせることで最大の効果を発揮する
- Job System:処理を複数スレッドに「分散」させる(並列化)
- Burst Compiler:コード自体を CPU が理解しやすいネイティブコードに「変換」する(高速化)
Job の種類
| 種類 | 用途 |
|---|---|
IJob | 1つの独立したタスクを実行 |
IJobParallelFor | 大量のデータ(配列)を分割して並列処理 |
IJobParallelForTransform | 大量の Transform の位置・回転を並列更新 |
IJob(単一タスク)
1つの大きな計算をバックグラウンドに逃がしたい時に使用
// struct として定義
public struct SimpleJob : IJob
{
public float Multiplier;
public NativeArray<float> Results;
public void Execute()
{
for (int i = 0; i < Results.Length; i++)
Results[i] *= Multiplier;
}
}
IJobParallelFor
大量のデータを複数スレッドで並列処理する場合に使う
[BurstCompile] // Burst の最適化対象になる
public struct ParallelJob : IJobParallelFor
{
[ReadOnly] public NativeArray<float> Input; // 読み込み専用
public NativeArray<float> Output;
public void Execute(int index)
{
Output[index] = Input[index] * Input[index];
}
}
..
// Schedule の第2引数:バッチサイズ(1スレッドあたりの処理件数)
JobHandle handle = job.Schedule(count, 64);
handle.Complete();
ParallelForTransform
Transform に対して動作するように特別に設計されている
TransformAccessArrayに渡されたすべてのTransformの位置・回転・スケールに対して同じ独立した処理を行う
[BurstCompile] // Burst の最適化対象になる
public struct MoveJob : IJobParallelForTransform
{
public float DeltaTime;
public void Execute(int index, TransformAccess transform)
{
transform.position += Vector3.up * DeltaTime;
}
}
Job の依存関係管理
複数の Job を連鎖させる場合、依存関係をJobHandleで管理する
void Start()
{
var data = new NativeArray<float>(1000, Allocator.TempJob);
// Job A:データを生成
var jobA = new GenerateJob { Data = data };
JobHandle handleA = jobA.Schedule();
// Job B:ジョブAの結果を使って処理(handleA を依存として渡す)
var jobB = new ProcessJob { Data = data };
JobHandle handleB = jobB.Schedule(handleA); // A完了後にBを実行
// Job C,D:Bの後に並列実行
var jobC = new OutputJobC { Data = data };
var jobD = new OutputJobD { Data = data };
JobHandle handleC = jobC.Schedule(handleB);
JobHandle handleD = jobD.Schedule(handleB);
// 複数の JobHandle をまとめて待つ
JobHandle.CombineDependencies(handleC, handleD).Complete();
data.Dispose();
}
NativeContainer(NativeArray)と Allocator の種類
Job 内でデータをやり取りするには、GC 管理外のNativeContainer(NativeArrayなど)が必要
ネイティブメモリへの比較的安全な C# ラッパーを提供するマネージドな値型「NativeContainer(NativeArray)」を使用する
- Job がメインスレッドのデータのコピーではなく、共有データにアクセスできるようにする
- GC の管理外のネイティブメモリに確保されるため GC が発生しない
// 通常の C# 配列 → GC の管理下・Job に渡せない
float[] managed = new float[1000];
// NativeArray → GC 管理外・Job に渡せる
NativeArray<float> native = new NativeArray<float>(1000, Allocator.TempJob);
NativeContainer(NativeArray)を使用する際、必要なメモリ割り当てのタイプ(Allocator)を指定する必要がある
| Allocator | 速度 | 寿命 | ジョブに渡せるか | Dispose |
|---|---|---|---|---|
Allocator.Temp | 最速 | 1フレーム以内 | 不可 | 不要(自動解放) |
Allocator.TempJob | 中間 | 4フレーム以内 | 可 | 必須 |
Allocator.Persistent | 最遅 | 無制限 | 可 | 必須 |
注意点・使い所
注意点
// NG①:Complete() 前に NativeArray にアクセスする
var results = new NativeArray<float>(10, Allocator.TempJob);
JobHandle handle = job.Schedule();
Debug.Log(results[0]); // エラー:Job 実行中
// OK①:Complete() 後にアクセスする
var results = new NativeArray<float>(10, Allocator.TempJob);
JobHandle handle = job.Schedule();
handle.Complete(); // Job 完了を待つ
Debug.Log(results[0]); // 完了後なので安全にアクセスできる
results.Dispose();
// NG②:NativeArray の Dispose 忘れ
var array = new NativeArray<float>(1000, Allocator.TempJob);
job.Schedule().Complete();
// Dispose がない → メモリリーク
// OK②:try / finally で確実に Dispose
var array = new NativeArray<float>(1000, Allocator.TempJob);
try
{
job.Schedule().Complete();
}
finally
{
array.Dispose();
}
使い所
向いている処理
├ 大量のオブジェクトの位置・物理計算
├ パスファインディング・AI の経路計算
├ 地形・メッシュの動的生成
├ 大量のパーティクルのシミュレーション
└ 画像・テクスチャの処理
向いていない処理
├ Unity の API を呼ぶ処理(GameObject・Transform の直接操作など)
├ 件数が少ない処理(スレッド管理コストの方が大きくなる)
└ 処理の依存関係が複雑でジョブ分割が難しい場合
参照
- https://docs.unity3d.com/6000.3/Documentation/Manual/job-system-overview.html
- https://docs.unity3d.com/ja/2023.2/Manual/JobSystem.html
- https://docs.unity3d.com/ja/2023.2/Manual/JobSystemCreatingJobs.html
- https://docs.unity3d.com/ja/2019.4/Manual/JobSystemNativeContainer.html
- https://docs.unity3d.com/Manual/job-system-native-container.html