【Unity】メモリ使用を減らす方法


この記事ではUnityでメモリを節約する方法を記載します。
メモリリークやメモリの無駄遣いをなくします。

メモリリーク部分の特定方法

Unity Profiler

UnityのProfilerを使用してメモリやCPUなどを監視できます。
さらにどの処理が原因かをおおよそ判定できます。

Deep Profiler

画面上のDeep Profilerを有効にすることで画面下のHierarchyのOverviewから見れるデータが増えます。

上記の例だとBehaviourUpdateの中のScriptAのUpdateメソッドが原因と出てきますが、有効だとさらにScriptAのUpdateから呼ばれたScriptBの別のメソッドが原因だと知ることができます。

その他の特定

PluginやiOS, AndroidなどはUnityだけでは判定できない部分もあります。
しかし、iOSの場合はデバッグビルドでより正確なデータを見ることが可能です。
どちらにしろ、まずはUnityの処理で問題がないことを確認したほうがよいでしょう。

  • PC
    • PCのシステムの機能でメモリを確認
  • iOS
    • XcodeのMemoryのグラフで確認
  • Android
    • AndroidStudioでメモリを確認
  • Web
    • ブラウザのデベロッパーツールのメモリ確認機能などで確認

メモリ節約のためにできること

対策としてできることを記載します。

ファイルの書き出し・読み込み – ★★★

単発では大した負荷になりませんが、Updateメソッドなどで頻繁に呼び出すと前回のが解放される前にメモリを消費し、蓄積していきます。

  • ローカルファイルへの書き出し・読み込みは管理用のScriptを作ってまとめる。
    • 1度読み込んだデータはキャッシュし、使用しなくなったタイミングで開放する。
    • アプリ終了時など決まったタイミングでのみデータを保存する。

管理クラスとしてSingletonを使用する場合は以下の記事をどうぞ

データ保存のタイミングに関しては以下の記事をどうぞ

ループ内での生成 – ★★★

ループ内でTextureやSpriteなどの生成を行うとループ中はメモリが蓄積します。
主な例として何千回とループするfor, whileやUpdateメソッド内での生成になります。

  • ループ中から別のメソッドを読んで生成処理を行う。
  • Startなど初期化メソッドで生成しておく

上のデータキャッシュに近い話です。

Singletonの使用 – ★★☆

クラスのインスタンスが無駄に複数あるものを1つにします。

  • Singletonで複数インスタンスの生成の必要がないものはまとめる。

Singletonは自動的に解放されないので使用しなくなったタイミングで明示的に開放しましょう。なんのクラスにでも多用すると逆効果です。

Resource – ★☆☆

Projectに追加している画像はTextureとして扱われ、無駄な画像数, サイズが指定されていると余計にメモリを消費していることがあります。

  • 使いまわせるロゴ・ボタン素材は集約し、容量も削減する。
  • Inspectorの設定を変更する
    • Max Sizeは適切なサイズにする
      • 500x500pxなどの場合は標準の2048から512に変更する。
    • Formatもクオリティの重要度に応じて色数を減らしてください
      • Compressed:標準
      • Truecolor:高画質
      • 16bit:低画質(透過なし)

明示的初期化 – ★☆☆

使用しない変数やクラスを明示的に初期化します。

Unityは.monoによる自動解放のGC(ガーベジコレクション)のため、定期的に使用していない変数やクラスをメモリから解放します。

なので使用しなくなったときに放置するのではなく、明示的に参照を消します。

  • Dispose()などの解放用のメソッドがある場合は呼ぶ。
  • nullが代入できる変数はnullにする。

解放後やnullに対して参照しようとすると参照エラーが発生するので注意してください。

また、解放されるのはGCのタイミングなので即時ではありません。

ページや機能を削減・分割 – ★☆☆

最終手段ですが、いくら開放してもメモリ不足になるのはそもそも動作環境のメモリが少ないためです。

メモリが少ない動作環境を見限って対応外にするか、機能を制限することで動作するように仕様変更します。

Leave a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です