Unity 도구로 메모리 사용량을 확인하는 방법

Android 시스템에서 메모리 제한기 (Android 17 이상)의 메모리 한도 임계값과 Google Play Console의 메모리 vitals 벤치마크 값은 '익명 RSS + 스왑'입니다. 이 값은 프로세스에서 실제로 차지하는 실제 메모리 압력 수준을 나타내며 안정적인 앱 운영을 위해 모니터링해야 하는 중요한 측정항목입니다.

현재 Unity 엔진 내에서 런타임 또는 정적으로 '익명 RSS + 스왑'과 정확히 일치하는 메모리 사용량을 측정하기는 어렵습니다.

이 문제를 해결하기 위해 이 페이지에서는 Unity 엔진 환경에서 Unity 프로파일러, ProfileRecorder API, Unity 메모리 프로파일러를 사용하여 근사치를 통해 높은 신뢰도로 '익명 RSS + 스왑' 값을 추적하는 방법을 소개합니다.

런타임에 메모리 사용량 확인

Unity에서는 오버헤드 없이 런타임에 Android의 정확한 '익명 RSS + 스왑' 메모리 사용량을 직접 측정하기가 어려울 수 있습니다. 하지만 Unity의 기본 제공 프로파일러 API를 사용하여 이 값을 (~10% 분산 내)에 가깝게 추정할 수 있습니다.

방법 1: 프로파일러 사용

다음 프로파일러 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를 사용하여 총 예약된 메모리Gfx 예약된 메모리 측정항목을 추적할 수 있습니다.

  • 개발 빌드: '총 예약된 메모리' - 'Gfx 예약된 메모리'를 계산합니다.

  • 출시 빌드: '총 예약된 메모리'를 직접 사용합니다.

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로 추적할 수 없습니다.

  • Unity 버전에 따라 이러한 API가 지원되지 않을 수 있습니다.

메모리 분석 분석 (정적 분석)

런타임에 메모리 사용량이 많은 것으로 감지되면 메모리가 사용되는 위치를 식별해야 합니다. 메모리 분포를 분석하면 불필요한 할당을 삭제하고 게임의 전반적인 메모리 사용 공간을 줄일 수 있습니다.

Unity 메모리 프로파일러

심층 메모리 분석을 실행하고 게임을 최적화하려면 Unity 메모리 프로파일러 패키지를 사용하세요. Android OS '익명 RSS + 스왑' 사용량에 해당하는 항목을 찾으려면 다음 단계를 따르세요.

  1. Unity 메모리 프로파일러를 사용하여 스냅샷을 캡처합니다.
  2. 스냅샷을 열고 모든 메모리 > 기기의 상주 메모리 로 이동합니다.
  3. 다음 항목의 합계를 계산합니다.

    • Untracked
    • Android 런타임
    • 네이티브
    • 관리됨
    Unity 메모리 프로파일러에서 상주 메모리로 설정하면 메모리 측정항목이 표시됨
    그림 1. 메모리 설명은 상주 메모리에 저장됩니다.

총합은 Android OS '익명 RSS + 스왑'을 실제로 대체하며 게임 메모리 분석에 실행 가능한 통계를 제공합니다.

제한사항:

  • 메모리 압력이 심한 경우 Android OS는 활성 메모리 페이지를 압축하거나 스왑하여 RAM을 확보할 수 있습니다. Unity 메모리 프로파일러는 스왑된 메모리를 추적할 수 없으므로 메모리 사용량이 많은 시나리오에서 불일치가 발생할 수 있습니다.

  • Unity 버전에 따라 이러한 기능이 제한될 수 있습니다.

더 정확한 평가

정확한 Android OS '익명 RSS + 스왑' 값을 확인하려면 Perfetto 를 사용하세요. 이를 통해 정확한 시스템 수준 메모리 사용량을 측정하고 게임의 메모리 사용 공간을 철저히 분석할 수 있습니다.