GC νμΉ λΆμ
Unreal Insightsμ GC νΈλ μ΄μ€λ₯Ό νμ©νμ¬ GC μ€νμ΄ν¬μ μμΈμ μ νν μ§λ¨ν©λλ€
GC νμΉμ μμΈ
νλ μ λλ‘μ μ λ°νλ GC κ΄λ ¨ μμΈλ€
μ£Όμ νμΉ μμΈ
| μμΈ | μ¦μ | ν΄κ²° λ°©ν₯ |
|---|---|---|
| λλ κ°μ²΄ Mark | UObject μμλ§ κ° | Cluster GC, DisregardForGC νλ |
| λλ κ°μ²΄ Sweep | νκΊΌλ²μ λ§μ νκ΄΄ | Incremental Destroy, Pooling |
| κ°μ Full GC | Incremental μ€ν¨ | κ°μ²΄ μμ± μλ μ μ΄ |
| BeginDestroy μ§μ° | GPU 리μμ€ λκΈ° | 리μμ€ μ¬μ ν΄μ |
| ν΄λ¬μ€ν° ν΄μ²΄ | μΈλΆ μ°Έμ‘° λ€μ | ν΄λ¬μ€ν° λ©€λ² μΈλΆ μ°Έμ‘° μ΅μν |
| AddReferencedObjects κ³ΌλΆν | 볡μ‘ν 컀μ€ν μΆμ | UPROPERTYλ‘ μ ν |
GC νμΉλ μ£ΌκΈ°μ μ΄κ³ μμΈ‘ λΆκ°λ₯ν©λλ€. gc.TimeBetweenPurgingPendingKillObjects κ°κ²©(κΈ°λ³Έ 60μ΄)λ§λ€ λ°μνκ±°λ, λ©λͺ¨λ¦¬ μλ° μ κ°μ μ€νλ©λλ€. μΌκ΄λ FPSκ° μ€μν κ²μμμλ λ°λμ Incremental GCλ₯Ό νμ©ν΄μΌ ν©λλ€.
Unreal Insights GC νΈλ μ΄μ€
Unreal Insightsλ‘ GC μ΄λ²€νΈλ₯Ό μμΈ λΆμ
Insightsμμ GC μΆμ
// 1. νΈλ μ΄μ€ μμ
// 컀맨λ λΌμΈ:
-trace=gc,memory,cpu
// λλ μ½μ:
Trace.Start gc,memory,cpu
// 2. Unreal Insightsμμ λΆμ
// Timing Viewμμ GC κ΄λ ¨ μ΄λ²€νΈ νμΈ:
CollectGarbage β μ 체 GC μκ°
βββ MarkReachable β Mark λ¨κ³ μκ°
β βββ GatherRoots β Root Set μμ§
β βββ ProcessObjects β μ°Έμ‘° μν
βββ UnhashUnreachable β Unreachable μμ§
βββ DestroyGarbage β κ°μ²΄ νκ΄΄
// 3. μ€νμ΄ν¬ νλ μ λΆμ
// νμΉ νλ μμ ν΄λ¦νμ¬ GC μ΄λ²€νΈ μμΈ νμΈ
// μ΄λ λ¨κ³κ° κ°μ₯ μ€λ 걸리λμ§ νμΈ
CPU νλ‘νμΌλ§κ³Ό GC μκ΄κ΄κ³
GCκ° μ 체 νλ μ μκ°μ λ―ΈμΉλ μν₯ λΆμ
stat unitκ³Ό GC νμΉ μ°κ΄
// νλ μ μκ° λΆν΄
stat unit
Frame: 25.3 ms β μ΄ νλ μ μκ° (40fps)
Game: 12.1 ms β κ²μ λ‘μ§
Draw: 8.2 ms β λ λλ§
GPU: 10.5 ms β GPU
Swap: 0.5 ms
// GCκ° Game μκ°μ ν¬ν¨λ¨
// GC νμΉ μ:
Frame: 45.3 ms β νμΉ! (22fps)
Game: 32.1 ms β κ²μ λ‘μ§ κΈμ¦ (GC ν¬ν¨)
Draw: 8.2 ms
GPU: 10.5 ms
// stat gameμΌλ‘ μμΈ λΆν΄
stat game
GarbageCollection: 20.0 ms β GCκ° μμΈ νμ !
t.HitchFrameTimeThresholdμ μ€μ νλ©΄ ν΄λΉ μκ°μ μ΄κ³Όνλ νλ μμ΄ μλμΌλ‘ λ‘κ·Έμ κΈ°λ‘λ©λλ€. GCκ° μμΈμΈ νμΉλ₯Ό μλ νμ§νλ λ° μ μ©ν©λλ€.
GC νμΉ ν΄κ²° μ λ΅
μμΈλ³ ꡬ체μ μΈ ν΄κ²° λ°©λ²
μμΈλ³ ν΄κ²°μ±
// μμΈ 1: Mark λ¨κ³κ° λλ¦Ό
// β Cluster GC νμ±ν
gc.CreateGCClusters 1
// β DisregardForGC νλ
gc.MaxObjectsNotConsideredByGC 500000
// β Incremental νμ±ν
gc.AllowIncrementalReachability 1
// μμΈ 2: Sweep/Destroyκ° λλ¦Ό
// β Incremental Destroy νμ±ν
gc.IncrementalBeginDestroyEnabled 1
// β Object Pooling λμ
// μμΈ 3: κ°μ Full GC λ°μ
// β μ¬μλ νμ μ¦κ°
gc.NumRetriesBeforeForcingGC 20
// β κ°μ²΄ μμ± μλ μ ν
// μμΈ 4: λΆνμν GC μ€ν
// β GC κ°κ²© μ‘°μ
gc.TimeBetweenPurgingPendingKillObjects 120.0
// β μ€μ μκ°μ GC μ΅μ
GEngine->DelayGarbageCollection();
ν΅μ¬ μμ½
- GC νμΉμ μ£Όμ μμΈμ λλ Mark, λλ Sweep, κ°μ Full GCμ λλ€
- Unreal Insightsμ GC νΈλ μ΄μ€λ‘ Mark/Sweep κ° λ¨κ³μ μμ μκ°μ λΆμν©λλ€
- stat unit + stat gameμΌλ‘ GCκ° νλ μ μκ°μ λ―ΈμΉλ μν₯μ νμΈν©λλ€
- μμΈλ³ ν΄κ²°: Cluster, Incremental, Pooling, GC κ°κ²© μ‘°μ λ±μ μ μ©ν©λλ€
- DelayGarbageCollection()μΌλ‘ μ€μ κ²μνλ μ΄ μκ°μ GCλ₯Ό μ΅μ ν μ μμ΅λλ€
λμ κ³Όμ
λ°°μ΄ λ΄μ©μ μ§μ μ€μ΅ν΄λ³΄μΈμ
10,000κ°μ UObjectλ₯Ό ν λ²μ μμ± ν μ°Έμ‘° ν΄μ νκ³ , ForceGarbageCollection()μ νΈμΆνμ¬ GC νμΉλ₯Ό μ¬ννμΈμ. stat unitμΌλ‘ ν΄λΉ νλ μμ Game Thread μκ° μ€νμ΄ν¬λ₯Ό μΈ‘μ νκ³ stat gcμ κ΅μ°¨ λΆμνμΈμ.
Unreal Insights(utrace)λ₯Ό νμ±ννκ³ GCκ° λ°μνλ ꡬκ°μ μΊ‘μ²νμΈμ. Timing λ·°μμ GarbageCollect μ΄λ²€νΈμ μ νν μμ μκ°κ³Ό μλΈ νμ€ν¬λ³ λΆν¬λ₯Ό λΆμνμΈμ.
κ²μνλ μ΄ μ€ GC νμΉλ₯Ό λ°©μ§νκΈ° μν μ’ ν© μμ€ν μ μ€κ³νμΈμ. κ°μ²΄ νλ§, μ μ§μ ν΄μ , GC νμ΄λ° μ μ΄(gc.TimeLimitSeconds), μ€μ ꡬκ°μμμ GC μ΅μ (IsIncrementalPurgePending) λ±μ μ‘°ν©ν μ λ΅μ ꡬννμΈμ.