600회 호출에서 1200회, 20회, 0회
Unity 6000.5.3f1 빈 프로젝트에서 문자열 경로를 120회 예열한 뒤 600번씩 호출했습니다. 현재 스레드의 Internal/GC.Alloc를 ProfilerRecorder로 합산하니 매 호출마다 $"Score: {score}"를 만든 경로는 1200회, 점수가 60회 호출마다 바뀔 때만 만든 경로는 20회, 같은 값 42를 가드 앞에 둔 경로는 0회였습니다. 이 숫자는 ProfilerRecorderSample.Count로 센 GC.Alloc 이벤트 수입니다. Recorder의 UnitType은 TimeNanoseconds였으므로 원시 Value를 바이트처럼 쓰지 않았습니다.
using TMPro;
using UnityEngine;
public sealed class ScoreLabel : MonoBehaviour
{
[SerializeField] private TMP_Text label;
private int shownScore = int.MinValue;
public void SetScore(int value)
{
if (value == shownScore)
return;
shownScore = value;
label.text = $"Score: {value}";
}
}배열 반환은 200회, 재사용 버퍼는 0회
40개의 SphereCollider를 쿼리 반경 안에 두고 Physics.OverlapSphere와 Physics.OverlapSphereNonAlloc을 각각 200번 호출했습니다. 배열을 반환하는 OverlapSphere에서는 200개의 GC.Alloc 이벤트가 잡혔고, 64칸 배열을 재사용한 NonAlloc 경로에서는 0개였습니다. 이 결과는 통제한 Editor 호출의 현재 스레드만 잰 값이며 실제 게임 한 프레임 전체의 할당량은 아닙니다.
using System;
using UnityEngine;
public sealed class NearbyTargets : MonoBehaviour
{
private const int MaxHits = 256;
[SerializeField] private float radius = 4f;
[SerializeField] private LayerMask targetMask;
private Collider[] hits = new Collider[32];
public int QueryNearby()
{
while (true)
{
int count = Physics.OverlapSphereNonAlloc(
transform.position, radius, hits, targetMask,
QueryTriggerInteraction.Collide);
if (count < hits.Length)
return count;
if (hits.Length >= MaxHits)
{
Debug.LogWarning($"Nearby target buffer reached {hits.Length}; result may be truncated.");
return count;
}
Array.Resize(ref hits, Math.Min(hits.Length * 2, MaxHits));
}
}
}반환값이 배열 길이와 같으면 포화로 취급합니다
활성 Collider가 정확히 8개일 때도 8칸 버퍼의 반환값은 8이었고, 활성 Collider가 40개일 때도 8이었습니다. count == hits.Length만 보고 정확히 다 담겼는지 잘렸는지 구분할 수 없습니다. 위 코드는 이 경우 배열을 늘려 다시 묻습니다. Array.Resize는 포화 순간에 할당하므로 시작 크기와 최대값은 실제 밀집도를 보고 정하고, 고정 상한에 닿으면 결과가 잘릴 수 있음을 남겨야 합니다.
실제 프로젝트에서는 대상 빌드에서 다시 잽니다
Development Build와 Autoconnect Profiler로 같은 장치, 씬, 입력을 반복하세요. CPU Usage의 GC Alloc 열에서 프레임을 고정하고 Allocation Call Stacks로 첫 할당 지점을 찾습니다. Deep Profile은 범위를 좁힌 뒤 잠깐만 켭니다. 목표는 숫자를 억지로 0으로 만드는 게 아니라 반복 호출에서 생기는 불필요한 할당을 없애는 것입니다.
직접 재현
검증일
검증 환경Unity 6000.5.3f1 (c2eb47b3a2a9), Windows 10 22H2 (10.0.19045) 64-bit, 기존 게임과 분리한 빈 프로젝트, Mono Editor, -batchmode -nographics -noUpm
Unity 6000.5.3f1 빈 프로젝트의 별도 Editor 프로세스 3회에서 문자열 경로와 Physics 쿼리를 직접 측정했습니다. 타임스탬프를 뺀 결과는 모두 같았습니다.