Unity ツールでメモリ使用量を確認する方法

Android システムでは、メモリ リミッター(Android 17 以降)のメモリ上限しきい値と、Google Play Console のメモリ Vitals のベンチマーク値は「匿名 RSS + スワップ」です。この値は、プロセスが実際に占有している物理メモリのプレッシャー レベルを表します。アプリの安定した動作を監視するためにモニタリングする必要がある重要な指標です。

現在、Unity Engine 内で実行時または静的に「匿名 RSS + スワップ」と完全に一致するメモリ使用量を測定することは困難です。

この問題を解決するため、このページでは、Unity Engine 環境で Unity Profiler、ProfileRecorder API、Unity Memory Profiler を使用して、近似値から「匿名 RSS + スワップ」の値を高い信頼性で追跡する方法について説明します。

実行時のメモリ使用量を確認する

Unity で、オーバーヘッドなしで実行時に Android の正確な「匿名 RSS + スワップ」メモリ使用量を直接測定することは難しい場合があります。ただし、Unity の組み込みプロファイラ API を使用すると、この値を(約 10% の誤差範囲内で)正確に推定できます。

方法 1: プロファイラを使用する

メモリ使用量の合計は、次の Profiler API から返された値を合計することで見積もることができます。

using UnityEngine;
using UnityEngine.Profiling;

public class MemoryMonitor : MonoBehaviour
{
    public long GetEstimatedMemoryUsageBytes()
    {
        long totalReserved = Profiler.GetTotalReservedMemoryLong();
        long monoHeapSize = Profiler.GetMonoHeapSizeLong();

        return totalReserved + monoHeapSize;
    }
}

方法 2: ProfilerRecorder クラスを使用する

ProfilerRecorder を使用して、Total Reserved Memory 指標と Gfx Reserved Memory 指標をトラッキングできます。

  • 開発ビルドの場合: 「Total Reserved Memory」 - 「Gfx Reserved Memory」を計算します。

  • リリースビルドの場合: 「Total Reserved Memory」を直接使用します。

using Unity.Profiling;
using UnityEngine;

public class MemoryMonitor : MonoBehaviour
{
    ProfilerRecorder totalRecorder;

#if DEVELOPMENT_BUILD
    ProfilerRecorder gfxRecorder;
#endif

    private void OnEnable()
    {
        totalRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Total Reserved Memory");

#if DEVELOPMENT_BUILD
        gfxRecorder = ProfilerRecorder.StartNew(ProfilerCategory.Memory, "Gfx Reserved Memory");
#endif
    }

    private void OnDisable()
    {
        totalRecorder.Dispose();

#if DEVELOPMENT_BUILD
        gfxRecorder.Dispose();
#endif
    }

    public long GetEstimatedMemoryUsageBytes()
    {
#if DEVELOPMENT_BUILD
        if (totalRecorder.Valid && gfxRecorder.Valid)
        {
            return totalRecorder.LastValue - gfxRecorder.LastValue;
        }
#else
        if (totalRecorder.Valid)
        {
            return totalRecorder.LastValue;
        }
#endif
        return 0;
    }
}

制限事項:

  • Unity のメモリ マネージャーをバイパスするメモリ割り当て(NativeMalloc(IntPtr size) など)は、これらの API で追跡できません。

  • これらの API は、Unity のバージョンによってはサポートされていない場合があります。

メモリの内訳を分析する(静的分析)

実行時にメモリ使用量が多いことが検出された場合は、メモリがどこで使用されているかを特定する必要があります。メモリ分布を分析することで、不要な割り当てを排除し、ゲーム全体のメモリ使用量を削減できます。

Unity Memory Profiler

メモリの詳細な分析を行い、ゲームを最適化するには、Unity Memory Profiler パッケージを使用します。Android OS の「匿名 RSS + スワップ」の使用量に対応する項目を見つけるには:

  1. Unity Memory Profiler を使用してスナップショットをキャプチャします。
  2. スナップショットを開き、[All of Memory] > [Resident Memory on Device] に移動します。
  3. 次の項目の合計を計算します。

    • 追跡対象外
    • Android ランタイム
    • ネイティブ
    • 管理対象
    Unity Memory Profiler で [Resident Memory] に設定すると表示されるメモリ指標
    図 1. メモリの説明は常駐メモリに保存されます

合計値は Android OS の「匿名 RSS + スワップ」の代わりとして機能し、ゲームのメモリ分析に役立つ実用的な分析情報を提供します。

制限事項:

  • メモリ負荷が高い場合、Android OS はアクティブなメモリページを圧縮またはスワップして RAM を解放することがあります。Unity Memory Profiler はスワップされたメモリを追跡できないため、メモリ使用量が多いシナリオでは不一致が発生する可能性があります。

  • これらの機能は、Unity のバージョンによって制限される場合があります。

より正確な評価

Android OS の正確な「匿名 RSS + スワップ」の値を確認するには、Perfetto を使用します。これにより、システムレベルのメモリ使用量を正確に測定し、ゲームのメモリ フットプリントを徹底的に分析できます。