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

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

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

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

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

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

方法 1: Profiler を使用する

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 の Memory Manager をバイパスするメモリ割り当て(NativeMalloc(IntPtr size) など)は、これらの API で追跡できません。

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

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

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

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 を使用します。これにより、システムレベルのメモリ使用量を正確に測定し、ゲームのメモリ使用量を徹底的に分析できます。

匿名 RSS、スワップ、それらの合計クエリを示す Perfetto UI。
図 2.匿名 RSS、スワップ、それらの合計クエリを示す Perfetto UI。