web-dev-qa-db-ja.com

Unity3D:ガベージコレクションを最適化する

Unity3D Profiler は、主にガベージコレクションに関するスパイクを表示します。下のスクリーンショットでは、3つの赤いスパイクは、ゲームプレイで使用した3つのストールを表しています。これらのストールはそれぞれ100ミリ秒以上で、ほとんどの時間はTrackDependenciesに費やされました。

nity命令 によると、これをコードに追加してみました:

if (Time.frameCount % 30 == 0)
{
    System.GC.Collect();
}

これは役に立ちませんでした。まだスパイクがあり、100ミリ秒以上かかります。正確には何が起こっているのでしょうか。また、ゲームを最適化するために何ができますか?

PS:

ゲーム内の多くのGameObjectを動的に作成および破棄しています。それは問題でしょうか?

post で洞窟化されたように、戻り値としてループまたは配列に文字列の連結がありません。

profiler

12
Zening Qu

これは役に立ちませんでした。まだスパイクがあり、100ミリ秒以上かかります。正確には何が起こっているのでしょうか。また、ゲームを最適化するために何ができますか?

System.GC.Collectを使用すると、ガベージコレクションを強制するだけです。前回の収集から割り当てを解除するために大量のメモリを割り当てた場合、スパイクを回避することはできません。これは、大規模な割り当て解除を回避して、ガベージコレクションを時間の経過とともに分散しようとする場合にのみ役立ちます。

ゲーム内の多くのGameObjectを動的に作成および破棄しています。それは問題でしょうか?

おそらくこれが問題である可能性があります。

いくつかのヒント:

  • アプリケーションの開始時に、できるだけ多くのリソース(LoadResourceおよびInstantiate)を割り当てるようにしてください。必要なメモリがそれほど多くない場合は、必要なすべてのリソースをインスタンス化し、オンデマンドでそれらを無効/有効にすることができます。リソースメモリの要件が膨大な場合、これは達成できません。
  • InstantiateおよびDestroyへのゲーム内呼び出しは避けてください。 オブジェクトのプールを作成します。ここで、アプリケーションの起動時にリソースのセットがインスタンス化されます。必要なリソースを有効にし、残りはすべて無効にします。オブジェクトを破棄する代わりに、オブジェクトをプールに解放して、オンデマンドで無効化および再実行可能にすることができます。
  • Resources.UnloadUnusedAssetsへのゲーム内呼び出しは避けてください。これにより、以前にリソースをリリースしたことがある場合にのみ、新しいリソースのインスタンス化に必要な時間が長くなります。メモリ使用量を最適化することは便利ですが、コストのかかる間隔で、またはオブジェクトを破棄するたびに呼び出すことは意味がありません。
13
Heisenbug