Post

2026-05-18 TIL (59일차)

2026-05-18 TIL (59일차)

[TIL] 언리얼 엔진: 하드 레퍼런스와 소프트 레퍼런스의 완벽 이해 및 활용

언리얼 엔진으로 개발을 하다 보면 가장 빈번하게 겪는 최적화 이슈 중 하나가 메모리 낭비와 초기 로딩 속도 저하다. 이 문제의 90%는 에셋을 참조하는 방식, 즉 레퍼런스(Reference) 구조에서 발생한다. 오늘은 메모리 관리의 핵심인 하드 레퍼런스와 소프트 레퍼런스의 차이를 정리해 본다.


1. 하드 레퍼런스 (Hard Reference) 란?

하드 레퍼런스는 객체가 다른 객체를 메모리 상에서 직접적(포인터)으로 꽉 쥐고 있는 상태를 말한다.

동작 방식

  • “연쇄 로딩(Cascading Load)”: A라는 객체가 메모리에 로드될 때, A가 하드 레퍼런스로 참조하고 있는 B도 무조건 함께 메모리에 로드된다.
  • 만약 B가 C를, C가 D를 하드 레퍼런스로 가지고 있다면? A 하나만 불렀을 뿐인데 A, B, C, D가 줄줄이 소시지처럼 모두 메모리에 올라가 버린다.

C++ 코드 예시

1
2
3
4
5
6
// 하드 레퍼런스 (강한 참조)
UPROPERTY(EditAnywhere)
UTexture2D* ItemIcon;

UPROPERTY(EditAnywhere)
TSubclassOf<AActor> BossMonsterClass;

언제 사용할까?

  • 해당 객체가 존재할 때 ‘반드시’ 존재해야만 하는 필수적인 에셋
  • 예: 캐릭터의 메인 스켈레탈 메시(Skeletal Mesh), 기본 장착 무기, 즉각적으로 반응해야 하는 기본 이펙트.
  • 장점: 이미 메모리에 올라와 있으므로, 접근 속도가 매우 빠르고 null 체크 후 즉시 사용할 수 있다.
  • 단점: 불필요한 상황에서도 메모리를 차지한다. (예: 인벤토리 UI를 열지도 않았는데, UI 위젯이 모든 아이템 아이콘을 하드 참조하고 있다면 게임 시작부터 아이콘 수백 개가 메모리를 갉아먹는다.)

(에디터에서 특정 에셋 우클릭 -> Reference Viewer (레퍼런스 뷰어)를 열어보면 하드 참조로 인해 엮인 메모리 연쇄 로드 트리를 확인할 수 있다.)


2. 소프트 레퍼런스 (Soft Reference) 란?

소프트 레퍼런스는 객체의 실제 메모리가 아니라, “그 객체가 어디 있는지 주소(경로, String)만” 들고 있는 상태다.

동작 방식

  • A가 B를 소프트 레퍼런스로 가지고 있다면, A가 메모리에 로드되어도 B는 로드되지 않는다. A는 그저 B의 경로만 알고 있을 뿐이다.
  • B가 실제로 필요한 순간에만 개발자가 코드를 통해 명시적으로 로드(동기/비동기)하여 메모리에 올린다.

C++ 코드 예시

1
2
3
4
5
6
// 소프트 레퍼런스 (약한 참조)
UPROPERTY(EditAnywhere)
TSoftObjectPtr<UTexture2D> ItemIcon; // 실제 에셋(오브젝트)

UPROPERTY(EditAnywhere)
TSoftClassPtr<AActor> BossMonsterClass; // 클래스 타입

언제 사용할까?

  • “언젠가 쓰일 수도 있지만, 지금 당장 무조건 필요한 것은 아닌” 무거운 에셋
  • 예: 인벤토리의 아이템 아이콘들, 특정 페이즈에만 스폰되는 거대 보스 몬스터, 방대한 오픈월드의 특정 구역 에셋, UI/사운드 파일들.
  • 장점: 초기 로딩 속도를 엄청나게 줄여주고, 사용하지 않는 메모리를 극적으로 절약할 수 있다.
  • 단점: 실제로 에셋을 띄우기 위해 로딩하는 시간(Delay)이 발생한다. 따라서 렉(Hitch)을 방지하기 위해 주로 FStreamableManager를 이용한 비동기 로딩(Async Loading) 작업이 수반되어야 한다.

하드 레퍼런스 vs 소프트 레퍼런스 요약

구분하드 레퍼런스 (Hard Reference)소프트 레퍼런스 (Soft Reference)
저장 형태메모리 포인터 직접 참조에셋 경로(주소) 문자열
로딩 시점부모 객체가 로드될 때 즉시 동반 로드개발자가 원할 때 명시적 로드 (동기/비동기)
메모리 점유항상 점유함 (무거움)필요할 때만 점유함 (가벼움)
접근 속도즉시 사용 가능 (가장 빠름)로딩 후 사용 가능 (로딩 딜레이 존재)
C++ 타입UObject*, TSubclassOf<T>TSoftObjectPtr<T>, TSoftClassPtr<T>
적합한 용도캐릭터 본체, 필수 컴포넌트, 주무기수백 개의 인벤토리 아이콘, 특수 몬스터, 맵 에셋
This post is licensed under CC BY 4.0 by the author.