์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ

Unity Addressables ์ˆœํ™˜ ์ฐธ์กฐ๋กœ ์ธํ•œ ์—์…‹ ๋ฒˆ๋“ค ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ์›์ธ๊ณผ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๊ฒŒ์ž„๊ต์ˆ˜ 2026. 8. 30. 13:01
๋ฐ˜์‘ํ˜•

๐ŸŒ English Abstract

This technical post explores memory leak issues and delayed asset release in Unity game development caused by circular references within the Addressable Asset System. It breaks down the internal reference counting mechanisms, implicit AssetBundle dependencies, and provides actionable troubleshooting steps using Memory Profiler and Event Viewer. Game developers will learn best practices for refactoring asset bundle structures, decoupling dynamic references, and optimizing runtime memory consumption.

์œ ๋‹ˆํ‹ฐ(Unity)์˜ ์–ด๋“œ๋ ˆ์„œ๋ธ” ์—์…‹ ์‹œ์Šคํ…œ(Addressable Asset System)์€ ๊ธฐ์กด์˜ ์—์…‹ ๋ฒˆ๋“ค(AssetBundle) ๊ด€๋ฆฌ ๋ฐฉ์‹๋ณด๋‹ค ํ›จ์”ฌ ์œ ์—ฐํ•˜๊ณ  ๊ณ ๋„ํ™”๋œ ๋™์  ๋ฆฌ์†Œ์Šค ๋กœ๋”ฉ(Dynamic Resource Loading) ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ๋‚˜ ๋ฆฌ์†Œ์Šค ๊ฐ„์˜ ๊ด€๊ณ„๊ฐ€ ๋ณต์žกํ•œ ํ™˜๊ฒฝ์—์„œ๋Š” ์ˆœํ™˜ ์ฐธ์กฐ(Circular Reference)๋กœ ์ธํ•ด ์—์…‹ ๋ฒˆ๋“ค์ด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ •์ƒ์ ์œผ๋กœ ํ•ด์ œ๋˜์ง€ ์•Š๊ณ  ์œ ํœด ์ƒํƒœ๋กœ ๋‚จ์•„์žˆ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜(Memory Leak) ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ์ง€์—ฐ(Delayed Unload) ํ˜„์ƒ์ด ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋ณธ ํฌ์ŠคํŒ…์—์„œ๋Š” ์–ด๋“œ๋ ˆ์„œ๋ธ”์˜ ๋‚ด๋ถ€ ๋™์ž‘ ์›๋ฆฌ์ธ ์ฐธ์กฐ ์นด์šดํŒ…(Reference Counting) ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‹ฌ๋„ ์žˆ๊ฒŒ ํŒŒํ—ค์น˜๊ณ , ์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ์™œ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ๋ฅผ ๋ฐฉํ•ดํ•˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ ์ง„๋‹จํ•˜๊ณ  ์•„ํ‚คํ…์ฒ˜์ ์œผ๋กœ ํ•ด๊ฒฐํ•˜๋Š” ์‹ค๋ฌด ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…(Troubleshooting) ๊ฐ€์ด๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.



1. Unity Addressables์˜ ์ฐธ์กฐ ์นด์šดํŒ… ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์ดํ•ด

Addressables ์‹œ์Šคํ…œ์€ ๋‚ด๋ถ€์ ์œผ๋กœ ์—์…‹๊ณผ ์—์…‹ ๋ฒˆ๋“ค์˜ ์ƒ๋ช…์ฃผ๊ธฐ(Lifecycle)๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ฐธ์กฐ ์นด์šดํŒ…(Reference Count) ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ์—์…‹์„ ๋กœ๋“œํ•  ๋•Œ๋งˆ๋‹ค ํ•ด๋‹น ์—์…‹์ด ์†ํ•œ ์—์…‹ ๋ฒˆ๋“ค์˜ ์ฐธ์กฐ ์นด์šดํ„ฐ๊ฐ€ ์ฆ๊ฐ€ํ•˜๊ณ , ๋ฐ˜๋Œ€๋กœ Addressables.Release() ๋˜๋Š” Addressables.ReleaseInstance()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ฐธ์กฐ ์นด์šดํ„ฐ๊ฐ€ ๊ฐ์†Œํ•ฉ๋‹ˆ๋‹ค.

  • ์ฐธ์กฐ ์นด์šดํŠธ = 0 (Reference Count zero): ์—์…‹ ๋ฒˆ๋“ค์— ์†ํ•œ ๋ชจ๋“  ์—์…‹์˜ ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ 0์— ๋„๋‹ฌํ•˜๋ฉด, ๋‚ด๋ถ€์ ์œผ๋กœ AssetBundle.Unload(true) ๋˜๋Š” AssetBundle.Unload(false)๊ฐ€ ์‹คํ–‰๋˜๋ฉฐ ํ•ด๋‹น ๋ฒˆ๋“ค์ด ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค.
  • ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„(Dependency Graph): ์—์…‹ A๊ฐ€ ์—์…‹ B๋ฅผ ์ง๊ฐ„์ ‘์ ์œผ๋กœ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ์—์…‹ A๋ฅผ ๋กœ๋“œํ•  ๋•Œ ์—์…‹ B๊ฐ€ ํฌํ•จ๋œ ๋ฒˆ๋“ค๊นŒ์ง€ ์ž๋™์œผ๋กœ ํ•จ๊ป˜ ๋ฉ”๋ชจ๋ฆฌ์— ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค.

์•”์‹œ์  ์˜์กด์„ฑ(Implicit Dependency)์˜ ํ•จ์ •

๊ฐœ๋ฐœ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ๋‘ ์—์…‹์„ ์—ฐ๊ฒฐํ•˜์ง€ ์•Š๋”๋ผ๋„, ์…ฐ์ด๋”(Shader), ๋จธํ‹ฐ๋ฆฌ์–ผ(Material), ์• ๋‹ˆ๋ฉ”์ด์…˜ ํด๋ฆฝ(Animation Clip) ๋“ฑ์˜ ๊ณตํ†ต ์—์…‹์ด ์„œ๋กœ ๋‹ค๋ฅธ ์–ด๋“œ๋ ˆ์„œ๋ธ” ๊ทธ๋ฃน(Addressable Group)์— ๋ถ„์‚ฐ๋˜์–ด ์žˆ์„ ๊ฒฝ์šฐ Unity ๋นŒ๋“œ ์‹œ์Šคํ…œ์€ ์•”์‹œ์  ์˜์กด์„ฑ(Implicit Dependency)์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ตฌ์กฐ์—์„œ ๊ด€๊ณ„๊ฐ€ ๊ผฌ์ด๋ฉด ์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ํ˜•์„ฑ๋ฉ๋‹ˆ๋‹ค.

2. ์ˆœํ™˜ ์ฐธ์กฐ(Circular Reference)๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ์ผ์œผํ‚ค๋Š” ์›์ธ

์ˆœํ™˜ ์ฐธ์กฐ๋Š” ๋‘ ๊ฐœ ์ด์ƒ์˜ ์—์…‹ ๋ฒˆ๋“ค์ด ์„œ๋กœ๋ฅผ ์ง๊ฐ„์ ‘์ ์œผ๋กœ ์ฐธ์กฐํ•˜๋ฉด์„œ ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ ์˜์›ํžˆ 0์œผ๋กœ ๋–จ์–ด์ง€์ง€ ์•Š๋Š” ์ƒํƒœ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

โš ๏ธ ๋Œ€ํ‘œ์ ์ธ ์ˆœํ™˜ ์ฐธ์กฐ ์‹œ๋‚˜๋ฆฌ์˜ค

  1. Bundle A์— ํฌํ•จ๋œ Prefab A๊ฐ€ Bundle B์˜ ScriptableObject B๋ฅผ ์ฐธ์กฐํ•จ (Bundle A โž” Bundle B ์˜์กด์„ฑ ์ƒ์„ฑ).
  2. Bundle B์— ํฌํ•จ๋œ Prefab B ๋˜๋Š” ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๊ฐ€ Bundle A์˜ Texture A๋ฅผ ์ฐธ์กฐํ•จ (Bundle B โž” Bundle A ์˜์กด์„ฑ ์ƒ์„ฑ).
  3. ๊ฐœ๋ฐœ์ž๊ฐ€ Prefab A๋ฅผ ํ•ด์ œ(Release)ํ•˜์—ฌ Bundle A์˜ ์ž์ฒด ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ๋‚ฎ์ถ”๋ ค๊ณ  ํ•˜์ง€๋งŒ, Bundle B๊ฐ€ ์—ฌ์ „ํžˆ Bundle A๋ฅผ ์˜์กดํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ Bundle A์˜ ์ฐธ์กฐ ์นด์šดํ„ฐ๋Š” 0์ด ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ƒํƒœ๊ฐ€ ์ง€์†๋˜๋ฉด Addressables.Release()๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ˜ธ์ถœํ•ด๋„ ๋ฉ”์ธ ๋ฉ”๋ชจ๋ฆฌ(RAM)์™€ VRAM์—์„œ ์—์…‹ ๋ฒˆ๋“ค์ด ์–ธ๋กœ๋“œ๋˜์ง€ ์•Š๋Š” ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ์ง€์—ฐ ๋ฐ ๋ˆ„์ˆ˜ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.



3. ์ˆœํ™˜ ์ฐธ์กฐ ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ์ง„๋‹จ ๋„๊ตฌ (Troubleshooting Tools)

๋ฌธ์ œ์˜ ์›์ธ์„ ๋ช…ํ™•ํžˆ ๊ทœ๋ช…ํ•˜๊ธฐ ์œ„ํ•ด Unity์—์„œ ์ œ๊ณตํ•˜๋Š” ํ‘œ์ค€ ํ”„๋กœํŒŒ์ผ๋ง ๋„๊ตฌ๋ฅผ ์กฐํ•ฉํ•˜์—ฌ ์ถ”์ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

โ‘  Addressables Event Viewer ํ™œ์šฉ

Unity ์ƒ๋‹จ ๋ฉ”๋‰ด์˜ Window > Asset Management > Addressables > Event Viewer๋ฅผ ํ†ตํ•ด ๋Ÿฐํƒ€์ž„ ์ค‘ ์—์…‹์˜ ์ฐธ์กฐ ์นด์šดํŠธ ๋ณ€๋™์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๊ฐ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํŠน์ • ์”ฌ(Scene)์„ ๋ฒ—์–ด๋‚˜๊ฑฐ๋‚˜ UI ํŒ์—…์„ ๋‹ซ์•˜์Œ์—๋„ ๊ทธ๋ž˜ํ”„์—์„œ ์ฐธ์กฐ ์นด์šดํŠธ(Ref Count)๊ฐ€ 0์œผ๋กœ ๋–จ์–ด์ง€์ง€ ์•Š๊ณ  ์ฃผํ™ฉ์ƒ‰/ํŒŒ๋ž€์ƒ‰ ์ŠคํŠธ๋ฆผ์ด ์œ ์ง€๋˜๋Š” ์—์…‹ ๋ฒˆ๋“ค์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

โ‘ก Unity Memory Profiler๋ฅผ ํ†ตํ•œ ๋ฉ”๋ชจ๋ฆฌ ์Šค๋ƒ…์ƒท ๋น„๊ต

Memory Profiler package๋ฅผ ํ™œ์šฉํ•ด ํ•ด์ œ ์ „/ํ›„์˜ ๋ฉ”๋ชจ๋ฆฌ ์Šค๋ƒ…์ƒท(Snapshot)์„ ์ฑ„์ทจํ•˜๊ณ  'Diff' ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. AssetBundleData ๋ฐ ObjectHeader ์„น์…˜์—์„œ ๋‚จ์•„์žˆ๋Š” ์—์…‹๋“ค์„ ์‹๋ณ„ํ•˜๊ณ  GC Handle Reference ์ถ”์ ์„ ํ†ตํ•ด ์ฐธ์กฐ ์ฒด์ธ์„ ์—ญ์ถ”์ (Backtracking)ํ•ฉ๋‹ˆ๋‹ค.

โ‘ข Addressables Build Layout Report ๋ถ„์„

Addressables ์„ค์ •์—์„œ Debug Build Layout์„ ํ™œ์„ฑํ™”ํ•˜๋ฉด ๋นŒ๋“œ ์‹œ Library/com.unity.addressables/buildlayout.txt ๋˜๋Š” JSON ํ˜•ํƒœ์˜ ๋ณด๊ณ ์„œ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ๊ฐ ๋ฒˆ๋“ค์ด ์–ด๋–ค ๋ฌต์‹œ์  ์—์…‹์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋Š”์ง€, ์–ด๋–ค ๋ฒˆ๋“ค๊ณผ ์˜์กด๊ด€๊ณ„๋ฅผ ๋งบ๊ณ  ์žˆ๋Š”์ง€ ์‹œ๊ฐ์ ์œผ๋กœ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4. ์‹ค๋ฌด ํ•ด๊ฒฐ ์ „๋žต ๋ฐ ์•„ํ‚คํ…์ฒ˜ ๋ฆฌํŒฉํ† ๋ง

์ˆœํ™˜ ์ฐธ์กฐ๋กœ ์ธํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹จ์ˆœ ์ฝ”๋”ฉ ์ˆ˜์ •์„ ๋„˜์–ด ์—์…‹ ๊ตฌ์กฐ์™€ ์ฝ”๋“œ ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„(Coupling)๋ฅผ ๋‚ฎ์ถ”๋Š” ์•„ํ‚คํ…์ฒ˜์  ๋ฆฌํŒฉํ† ๋ง(Refactoring)์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ „๋žต 1: ๊ณต์œ  ์—์…‹์˜ ์ „์šฉ ๊ทธ๋ฃน ๋ถ„๋ฆฌ (Extract Shared Dependencies)

๋‘ ๊ฐœ ์ด์ƒ์˜ ์–ด๋“œ๋ ˆ์„œ๋ธ” ๊ทธ๋ฃน์—์„œ ๊ณ ์œ ํ•˜๊ฒŒ ์ฐธ์กฐํ•˜๋Š” ๊ณตํ†ต ๋ฆฌ์†Œ์Šค(๊ณต์šฉ ๋จธํ‹ฐ๋ฆฌ์–ผ, ์•„ํ‹€๋ผ์Šค ํ…์Šค์ฒ˜, ์‚ฌ์šด๋“œ ์—์…‹ ๋“ฑ)๋ฅผ ๋ณ„๋„์˜ 'Shared_Assets' ์ „์šฉ ๊ทธ๋ฃน์œผ๋กœ ๋ถ„๋ฆฌํ•˜์„ธ์š”.

๊ธฐ์กด (๋ฌธ์ œ ๋ฐœ์ƒ ๊ตฌ์กฐ):
Group A (Prefab A, Shared Material) leftrightarrow Group B (Prefab B, Shared Material)
๐Ÿ‘‰ ๋ฒˆ๋“ค ๊ฐ„ ์•”์‹œ์  ์ˆœํ™˜ ์˜์กด์„ฑ ๋ฐœ์ƒ


๊ฐœ์„  (๋ถ„๋ฆฌ๋œ ๊ตฌ์กฐ):
Group A (Prefab A) โž” Shared Group (Shared Material)
Group B (Prefab B) โž” Shared Group (Shared Material)
๐Ÿ‘‰ ๋‹จ๋ฐฉํ–ฅ ์˜์กด์„ฑ์œผ๋กœ ๋ณ€๊ฒฝ๋˜์–ด ์ˆœํ™˜ ๊ณ ๋ฆฌ ์ฐจ๋‹จ

์ „๋žต 2: ํ•˜๋“œ ์ฐธ์กฐ๋ฅผ ์•ฝํ•œ ์ฐธ์กฐ(Weak Reference)๋กœ ์ „ํ™˜

C# ์Šคํฌ๋ฆฝํŠธ์—์„œ [SerializeField] private GameObject targetPrefab;๊ณผ ๊ฐ™์ด ์ง๋ ฌํ™”๋œ ์ง์ ‘ ์ฐธ์กฐ(Hard Reference)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€์‹ , AssetReference ๋˜๋Š” ์–ด๋“œ๋ ˆ์„œ๋ธ” Key(String/GUID)๋ฅผ ํ†ตํ•œ ์ง€์—ฐ ๋กœ๋”ฉ(Lazy Loading) ๋ฐฉ์‹์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

// Bad Case: ํ•˜๋“œ ์ฐธ์กฐ๋กœ ์ธํ•œ ์—์…‹ ๋ฒˆ๋“ค ๊ฐ„ ๊ฐ•๋ ฅํ•œ ๊ฒฐํ•ฉ ๋ฐ ์ˆœํ™˜ ์ฐธ์กฐ ์œ„ํ—˜ public class CharacterUI : MonoBehaviour { [SerializeField] private GameObject detailInfoPrefab; // Direct Hard Reference! } // Good Case: AssetReference ๋˜๋Š” Key๋ฅผ ์‚ฌ์šฉํ•œ ๋””์ปคํ”Œ๋ง (Decoupling) public class CharacterUI : MonoBehaviour { [SerializeField] private AssetReferenceGameObject detailInfoPrefabRef; public async Task LoadDetailWindowAsync() { // ํ•„์š” ์‹œ์ ์— ๋™์  ๋กœ๋“œ (๋‹จ๋ฐฉํ–ฅ ์ƒ๋ช…์ฃผ๊ธฐ ์ œ์–ด) AsyncOperationHandle handle = detailInfoPrefabRef.InstantiateAsync(); await handle.Task; } public void CloseDetailWindow(GameObject instance) { // ์‚ฌ์šฉ ์™„๋ฃŒ ํ›„ ๋ช…์‹œ์  ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ Addressables.ReleaseInstance(instance); } }

์ „๋žต 3: ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜(Event-Driven Architecture) ์ ์šฉ

์—์…‹ ๋˜๋Š” ์Šคํฌ๋ฆฝํŠธ ๊ฐ„์˜ ์ง์ ‘์ ์ธ ์ƒํ˜ธ์ž‘์šฉ์ด ํ•„์š”ํ•  ๋•Œ๋Š” C# Event, ScriptableObject ๊ธฐ๋ฐ˜ Event Channel, ๋˜๋Š” ์˜์กด์„ฑ ์—ญ์ „ ์›์น™(Dependency Inversion Principle)์„ ์ ์šฉํ•˜์—ฌ ์—์…‹ ๊ฐ„ ๋ฌผ๋ฆฌ์  ์—ฐ๊ฒฐ ๊ณ ๋ฆฌ๋ฅผ ๋Š์–ด๋ƒ…๋‹ˆ๋‹ค.

์ „๋žต 4: ์—์ง€ ์ผ€์ด์Šค(Edge Cases) ์กฐ์น˜ - Resources.UnloadUnusedAssets ๋ฐ GC ๊ฐ•์ œ ์‹คํ–‰

๊ฐ„ํ˜น Addressables์˜ ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ 0์ด ๋˜์—ˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , C# ํž™(Heap) ๋ฉ”๋ชจ๋ฆฌ์— ๋‚จ์•„์žˆ๋Š” GC Object๊ฐ€ ์—์…‹์˜ Native C++ Object๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ  ์žˆ์–ด ์‹ค์ œ Unload๊ฐ€ ์ง€์—ฐ๋˜๋Š” ์—์ง€ ์ผ€์ด์Šค๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์”ฌ ์ „ํ™˜ ์‹œ์ ์ด๋‚˜ ๋ฉ”๋ชจ๋ฆฌ ์ •๋ฆฌ ํƒ€์ด๋ฐ์— ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ ์ ˆํžˆ ์กฐ์œจํ•˜์—ฌ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

public System.Collections.IEnumerator ForceUnloadUnusedMemory() { // 1. C# ํž™ ๋ฉ”๋ชจ๋ฆฌ์˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฐ€๋น„์ง€ ์ˆ˜๊ฑฐ System.GC.Collect(); // 2. ๋น„๋™๊ธฐ๋กœ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” Native ์—์…‹ ์™„์ „ํžˆ ์–ธ๋กœ๋“œ AsyncOperation unloadOp = Resources.UnloadUnusedAssets(); yield return unloadOp; // 3. ํ•„์š” ์‹œ GC ์žฌํ˜ธ์ถœํ•˜์—ฌ ๊นจ๋—ํ•œ ํž™ ์ƒํƒœ ์œ ์ง€ System.GC.Collect(); }


๊ฒฐ๋ก  ๋ฐ ๊ถŒ์žฅ ์ฒดํฌ๋ฆฌ์ŠคํŠธ (Best Practices)

Unity Addressables๋ฅผ ์ด์šฉํ•œ ๋™์  ๋ฆฌ์†Œ์Šค ๊ด€๋ฆฌ ์‹œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์„ค๊ณ„ ๋‹จ๊ณ„๋ถ€ํ„ฐ ์—์…‹ ๊ฐ„์˜ ์˜์กด์„ฑ ๊ตฌ์กฐ๋ฅผ ์ตœ์ ํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ํ•ต์‹ฌ ์ฒดํฌ๋ฆฌ์ŠคํŠธ๋ฅผ ์ •๊ธฐ์ ์œผ๋กœ ๊ฒ€ํ† ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

  • [ ] ๊ทธ๋ฃน ๋ถ„๋ฆฌ ๊ทœ์น™ ํ™•๋ฆฝ: ์ž์ฃผ ๋ณ€๊ฒฝ๋˜๋Š” ์—์…‹๊ณผ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ •์  ์—์…‹์˜ ๊ทธ๋ฃน์„ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„ํ–ˆ๋Š”๊ฐ€?
  • [ ] Addressables Event Viewer ์ •๊ธฐ ์ ๊ฒ€: ํ•ต์‹ฌ ์ฝ˜ํ…ํŠธ ๋กœ๋“œ/ํ•ด์ œ ์ฃผ๊ธฐ์—์„œ ์ฐธ์กฐ ์นด์šดํ„ฐ๊ฐ€ ์ž”์กดํ•˜์ง€ ์•Š๋Š”์ง€ ๊ฒ€์ฆํ–ˆ๋Š”๊ฐ€?
  • [ ] ํ•˜๋“œ ์ฐธ์กฐ ์ตœ์†Œํ™”: Prefab ๋‚ด์— ๋‹ค๋ฅธ ์–ด๋“œ๋ ˆ์„œ๋ธ” ๊ทธ๋ฃน ์—์…‹์— ๋Œ€ํ•œ ์ง์ ‘ [SerializeField] ์ฐธ์กฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๊ฐ€?
  • [ ] Release ์Œ ์ผ์น˜: LoadAssetAsync ๋˜๋Š” InstantiateAsync ํ˜ธ์ถœ ํšŸ์ˆ˜์™€ Release / ReleaseInstance ํ˜ธ์ถœ ํšŸ์ˆ˜๊ฐ€ 1:1๋กœ ์ผ์น˜ํ•˜๋Š”๊ฐ€?

์ฒด๊ณ„์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ํ”„๋กœํŒŒ์ผ๋ง๊ณผ ์—์…‹ ๋ฆฌํŒฉํ† ๋ง ๊ธฐ๋ฒ•์„ ์ ์šฉํ•˜๋ฉด, ์ˆœํ™˜ ์ฐธ์กฐ๋กœ ์ธํ•œ ๋ฆฌ์†Œ์Šค ํ•ด์ œ ์ง€์—ฐ์„ ์™„๋ฒฝํ•˜๊ฒŒ ์˜ˆ๋ฐฉํ•˜๊ณ  ๋ชจ๋ฐ”์ผ ๋ฐ ๋ฉ€ํ‹ฐํ”Œ๋žซํผ ํ™˜๊ฒฝ์—์„œ ์•ˆ์ •์ ์ธ ํ”„๋ ˆ์ž„ ์œ ์ง€์™€ ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™”๋ฅผ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•