Serialization๊ณผ GC
Archive ์์คํ , UPROPERTY ํ๋๊ทธ, SaveGame ์ง๋ ฌํ๊ฐ GC์ ์ด๋ป๊ฒ ์ํธ์์ฉํ๋์ง ๋ถ์ํฉ๋๋ค
Archive ์์คํ ๊ฐ์
FArchive๋ฅผ ํตํ ์ง๋ ฌํ์ ๊ธฐ๋ณธ ์๋ฆฌ์ GC ๊ด๋ จ ์์นด์ด๋ธ
FArchive์ ์ญํ
FArchive๋ UE์ ์ง๋ ฌํ/์ญ์ง๋ ฌํ ์ถ์ ํด๋์ค์
๋๋ค. GC์ ๊ด๋ จ๋ ํน์ ์์นด์ด๋ธ์ธ FArchiveUObject๋ UObject ์ฐธ์กฐ๋ฅผ ์ง๋ ฌํํ ๋ GC๊ฐ ์ด ์ฐธ์กฐ๋ฅผ ์ถ์ ํ ์ ์๋๋ก ๋ณด์ฅํฉ๋๋ค.
// FArchive ๊ธฐ๋ณธ ์ฌ์ฉ
void UMyObject::Serialize(FArchive& Ar)
{
Super::Serialize(Ar);
// UPROPERTY๊ฐ ์๋ ๋ฐ์ดํฐ์ ์๋ ์ง๋ ฌํ
Ar << CustomData;
// UObject ์ฐธ์กฐ ์ง๋ ฌํ (GC ์ฐธ์กฐ ์๋ ๋ฑ๋ก)
Ar << ReferencedObject;
}
// GC ๊ด๋ จ ์ฃผ์ ์์นด์ด๋ธ ํ์
FArchiveUObject // UObject ์ฐธ์กฐ ์ง๋ ฌํ ๊ธฐ๋ณธ
FReferenceCollectorArchive // GC ์ฐธ์กฐ ์์ง ์ ์ฉ
FArchiveSaveTaggedProperties // ํ๊ทธ๋ ํ๋กํผํฐ๋ง ์ ์ฅ
FArchiveCountMem // ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๊ณ์ฐ
์ง๋ ฌํ ๊ณผ์ ์์ UObject ์ฐธ์กฐ๋ฅผ operator<<๋ก ์ฒ๋ฆฌํ๋ฉด, FArchiveUObject๊ฐ ํด๋น ์ฐธ์กฐ๋ฅผ ์ธ์ํ์ฌ ๋ก๋ ์ ์ฌ๋ฐ๋ฅธ ๊ฐ์ฒด๋ก ์ฐ๊ฒฐํฉ๋๋ค. ์ด๋ GC์ ์ฐธ์กฐ ๊ทธ๋ํ์๋ ๋ณ๊ฐ์ด์ง๋ง, ์ญ์ง๋ ฌํ ์ GC ์ฐธ์กฐ๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ๋ณต์ํ๋ ๋ฐ ํ์์ ์
๋๋ค.
UPROPERTY ์ง๋ ฌํ ํ๋๊ทธ
ํ๋กํผํฐ ์ง์ ์๊ฐ ์ง๋ ฌํ์ GC์ ๋ฏธ์น๋ ์ํฅ
์ง๋ ฌํ ๊ด๋ จ UPROPERTY ์ง์ ์
| ์ง์ ์ | ์ง๋ ฌํ | GC ์ถ์ | ์ค๋ช |
|---|---|---|---|
UPROPERTY() |
์๋ | ์ถ์ ๋จ | ๊ธฐ๋ณธ - ์ ์ฅ ๋ฐ GC ๋ชจ๋ ํ์ฑ |
Transient |
์ ์ธ | ์ถ์ ๋จ | ์ ์ฅ ์ ๋จ, GC๋ ์ ์ ์ถ์ |
DuplicateTransient |
์๋ | ์ถ์ ๋จ | ๋ณต์ ์์๋ง ์ ์ธ |
NonTransactional |
์๋ | ์ถ์ ๋จ | Undo/Redo ํธ๋์ญ์ ์ ์ธ |
SaveGame |
์ธ์ด๋ธ ํฌํจ | ์ถ์ ๋จ | ์ธ์ด๋ธ ๊ฒ์ ์ง๋ ฌํ์ ํฌํจ |
SkipSerialization |
์์ ์ ์ธ | ์ถ์ ๋จ | ๋ชจ๋ ์ง๋ ฌํ์์ ์ ์ธ |
Transient์ด๋ SkipSerialization์ ์ง๋ ฌํ๋ง ์ ์ธํ ๋ฟ, GC ์ฐธ์กฐ ์ถ์ ์ ์ฌ์ ํ ํ์ฑ์
๋๋ค. UPROPERTY()๋ก ์ ์ธํ UObject* ์ฐธ์กฐ๋ ์ด๋ค ์ง๋ ฌํ ํ๋๊ทธ๋ฅผ ์ฌ์ฉํ๋ GC๊ฐ ์ถ์ ํฉ๋๋ค. ๋ฐ๋๋ก UPROPERTY๊ฐ ์์ผ๋ฉด ์ง๋ ฌํ๋ GC ์ถ์ ๋ ๋์ง ์์ต๋๋ค.
UCLASS()
class UGameState : public UObject
{
GENERATED_BODY()
// ์ ์ฅ + GC ์ถ์
UPROPERTY(SaveGame)
int32 PlayerLevel;
// GC ์ถ์ ๋ง, ์ ์ฅ ์ ๋จ
UPROPERTY(Transient)
UTexture2D* CachedTexture;
// ์ ์ฅ + GC ์ถ์ (์ธ์ด๋ธ์๋ ํฌํจ)
UPROPERTY(SaveGame)
TArray<UItem*> Inventory;
};
SaveGame ์ง๋ ฌํ์ GC
์ธ์ด๋ธ ๊ฒ์ ์์คํ ์์ UObject ์ฐธ์กฐ๋ฅผ ์์ ํ๊ฒ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ
USaveGame๊ณผ ๊ฐ์ฒด ์ฐธ์กฐ
USaveGame ํด๋์ค๋ ๊ฒ์ ์ํ๋ฅผ ๋์คํฌ์ ์ ์ฅํฉ๋๋ค. ๊ทธ๋ฌ๋ UObject ์ฐธ์กฐ๋ฅผ ์ง์ ์ ์ฅํ ์๋ ์์ต๋๋ค - ๊ฐ์ฒด ํฌ์ธํฐ๋ ์ธ์
๊ฐ ์ ํจํ์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค.
UCLASS()
class UMySaveGame : public USaveGame
{
GENERATED_BODY()
// ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ: ๊ฐ ๋ฐ์ดํฐ ์ ์ฅ
UPROPERTY(SaveGame)
int32 Score;
// ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ: ์ํํธ ์ฐธ์กฐ๋ก ์์
๊ฒฝ๋ก ์ ์ฅ
UPROPERTY(SaveGame)
TSoftObjectPtr<UStaticMesh> EquippedMesh;
// ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ: ๊ตฌ์กฐ์ฒด๋ก ๋ฐ์ดํฐ ์ ์ฅ
UPROPERTY(SaveGame)
TArray<FItemSaveData> SavedItems;
// ์๋ชป๋ ๋ฐฉ๋ฒ: UObject* ์ง์ ์ ์ฅ
// UPROPERTY(SaveGame)
// UItem* EquippedItem; // ๋ก๋ ์ ๋๊ธ๋ง!
};
// ์ธ์ด๋ธ/๋ก๋ ์ฌ์ฉ๋ฒ
UMySaveGame* SaveObj = NewObject<UMySaveGame>();
SaveObj->Score = CurrentScore;
UGameplayStatics::SaveGameToSlot(SaveObj, "Slot1", 0);
// SaveObj๋ ์ดํ GC ๋์ (์ฐธ์กฐ ์ ์ง ํ์ ์ UPROPERTY์ ์ ์ฅ)
TSoftObjectPtr์ ์ฝํ ์ฐธ์กฐ์ด๋ฏ๋ก ๋์ ์์
์ด GC๋ ์ ์์ต๋๋ค. ์ค์ ์ฌ์ฉ ์ ์ LoadSynchronous()๋ ๋น๋๊ธฐ ๋ก๋๋ก ์์
์ ๋ก๋ํด์ผ ํฉ๋๋ค. ๋ก๋๋ ์์
์ ์ ์งํ๋ ค๋ฉด ๋ณ๋์ ๊ฐํ ์ฐธ์กฐ(UPROPERTY UObject*)๊ฐ ํ์ํฉ๋๋ค.
ํจํค์ง ๋ก๋ฉ๊ณผ GC ์ํธ์์ฉ
์์ ๋ก๋ฉ/์ธ๋ก๋ฉ ์ GC ๋์๊ณผ ์ฐธ์กฐ ํด๊ฒฐ
ํจํค์ง ๋ก๋ ์ GC ๊ณ ๋ ค์ฌํญ
์์ ํจํค์ง๊ฐ ๋ก๋๋๋ฉด ๋ด๋ถ์ ๋ชจ๋ UObject๊ฐ ์์ฑ๋๊ณ GUObjectArray์ ๋ฑ๋ก๋ฉ๋๋ค. ์ญ์ง๋ ฌํ ๊ณผ์ ์์ FObjectImport๋ฅผ ํตํด ์ธ๋ถ ์ฐธ์กฐ๊ฐ ํด๊ฒฐ๋๋ฉฐ, ์ด ์ฐธ์กฐ๋ค์ด GC ๊ทธ๋ํ์ ๋ฐ์๋ฉ๋๋ค.
// ํจํค์ง ๋ก๋ ์ GC ๊ด๋ จ ํ๋ฆ
LoadPackage()
โโโ CreateExport() // UObject ์ธ์คํด์ค ์์ฑ
โ โโโ NewObject() // GUObjectArray ๋ฑ๋ก
โโโ Serialize() // ํ๋กํผํฐ ์ญ์ง๋ ฌํ
โ โโโ ResolveImport() // ์ธ๋ถ ์ฐธ์กฐ ํด๊ฒฐ
โโโ PostLoad() // ๋ก๋ ํ ์ด๊ธฐํ
โโโ ConditionalPostLoad() // ์กฐ๊ฑด๋ถ ํ์ฒ๋ฆฌ
// ํจํค์ง ์ธ๋ก๋ ์
UnloadPackage()
โโโ ๋ด๋ถ ๊ฐ์ฒด๋ค์ ์ฐธ์กฐ ํด์
โโโ MarkAsGarbage() // ๊ฐ๋น์ง ๋งํน
โโโ ๋ค์ GC ์ฌ์ดํด์์ ์ค์ ์์ง
// ๊ฐ์ GC์ ํจํค์ง ์ธ๋ก๋
CollectGarbage(GARBAGE_COLLECTION_KEEPFLAGS);
// ๋๋
GEngine->ForceGarbageCollection(true);
FSoftObjectPath์ TSoftObjectPtr๋ ์์
๊ฒฝ๋ก๋ง ์ ์ฅํ๋ฏ๋ก ๋์ ํจํค์ง๋ฅผ ์ฆ์ ๋ก๋ํ์ง ์์ต๋๋ค. ์ด๋ GC์๋ ์ํฅ์ ๋ฏธ์น์ง ์์ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ธ ์์
๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค. ์ค์ ์ฌ์ฉ ์์ ์ ๋น๋๊ธฐ ๋ก๋๋ฅผ ์์ฒญํ๋ ๊ฒ์ด ๊ถ์ฅ ํจํด์
๋๋ค.
ํต์ฌ ์์ฝ
- FArchive ์์คํ ์ ์ง๋ ฌํ์ GC ์ฐธ์กฐ๋ฅผ ๋ชจ๋ ๊ด๋ฆฌํ๋ฉฐ, FArchiveUObject๊ฐ UObject ์ฐธ์กฐ๋ฅผ ํน๋ณ ์ฒ๋ฆฌํฉ๋๋ค
- Transient, SkipSerialization ๋ฑ์ ํ๋๊ทธ๋ ์ง๋ ฌํ๋ง ์ ์ดํ๋ฉฐ, GC ์ถ์ ์๋ ์ํฅ์ ๋ฏธ์น์ง ์์ต๋๋ค
- SaveGame์์ UObject ํฌ์ธํฐ๋ฅผ ์ง์ ์ ์ฅํ๋ฉด ์ ๋๋ฉฐ, TSoftObjectPtr๋ ๊ตฌ์กฐ์ฒด ๋ฐ์ดํฐ๋ก ๋ณํํด์ผ ํฉ๋๋ค
- ํจํค์ง ๋ก๋ ์ ์ญ์ง๋ ฌํ๋ฅผ ํตํด GC ์ฐธ์กฐ ๊ทธ๋ํ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ๋ณต์๋ฉ๋๋ค
- TSoftObjectPtr๋ ์ฝํ ์ฐธ์กฐ์ด๋ฏ๋ก ๋์์ด GC๋ ์ ์์ผ๋ฉฐ, ์ฌ์ฉ ์ ๋ช ์์ ๋ก๋๊ฐ ํ์ํฉ๋๋ค
๋์ ๊ณผ์
๋ฐฐ์ด ๋ด์ฉ์ ์ง์ ์ค์ตํด๋ณด์ธ์
UPROPERTY์ Transient, DuplicateTransient, SaveGame ํ๋๊ทธ๋ฅผ ๊ฐ๊ฐ ์ ์ฉํ ํ๋กํผํฐ๋ค์ด ํฌํจ๋ UObject๋ฅผ ๋ง๋ค๊ณ , FArchive๋ฅผ ํตํด ์ง๋ ฌํํ ๋ ์ด๋ค ํ๋กํผํฐ๊ฐ ํฌํจ๋๋์ง ํ์ธํ์ธ์.
TSoftObjectPtr๊ณผ ํ๋ ๋ ํผ๋ฐ์ค(UPROPERTY UObject*)๋ฅผ ๋ชจ๋ ํฌํจํ SaveGame ๋ฐ์ดํฐ ํด๋์ค๋ฅผ ๋ง๋ค๊ณ , FMemoryWriter/FMemoryReader๋ก ์ ์ฅ/๋ก๋ ์ฌ์ดํด์ ๊ตฌํํ์ฌ GC ํ ์ฐธ์กฐ ์ ํจ์ฑ์ ํ ์คํธํ์ธ์.
FArchiveUObject๋ฅผ ์์๋ฐ์ ์ง๋ ฌํ ๊ณผ์ ์์ ๋ฐ๊ฒฌ๋๋ ๋ชจ๋ UObject ์ฐธ์กฐ๋ฅผ ์์งํ๋ ์ปค์คํ ์์นด์ด๋ธ๋ฅผ ๊ตฌํํ์ธ์. ์ด๋ฅผ ํตํด ํน์ ๊ฐ์ฒด์ ์ง๋ ฌํ ์ฐธ์กฐ ๊ทธ๋ํ๋ฅผ ์์ฑํ๊ณ GC ์ฐธ์กฐ ์ถ์ ๊ณผ ๋น๊ตํ์ธ์.