1. ์ธ๋ฆฌ์ผ ์์ง์ ์๋ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ
๐ C++ ์ธ์ด ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ์ ๋ฌธ์ ์
- C++์ ์ ์์ค์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ์ฃผ์์ ์ง์ ์ ๊ทผํ๋ ํฌ์ธํฐ๋ฅผ ์ฌ์ฉํด ์ค๋ธ์ ํธ๋ฅผ ๊ด๋ฆฌํ๋ค.
- ๊ทธ๋ฌ๋ค๋ณด๋ ํ๋ก๊ทธ๋๋จธ๊ฐ ์ง์ ํ ๋น(new)์ ํด์ง(delete) ์ง ๋ง์ถ๊ธฐ๋ฅผ ํด์ผํ๋ค.
- ์ด๋ฅผ ์ ์งํค์ง ๋ชปํ๋ ๊ฒฝ์ฐ ๋ค์ํ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์
- ์๋ชป๋ ํฌ์ธํฐ ์ฌ์ฉ ์์
- ๋ฉ๋ชจ๋ฆฌ ๋์ : new๋ฅผ ํ๋๋ฐ delete ์ง์ ๋ง์ถ์ง ๋ชปํจ. ํ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ทธ๋๋ก ๋จ์์๋ ๊ฒฝ์ฐ
- ํ์ ํฌ์ธํฐ : ๋ค๋ฅธ ๊ณณ์์ ์ด๋ฏธ ํด์ ํด ๋ฌดํจํ๋ ์ค๋ธ์ ํธ์ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ
- ์์ผ๋ ํฌ์ธํฐ : ๊ฐ์ด ์ด๊ธฐํ๋์ง ์์ ์๋ฑํ ์ฃผ์๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ
- ์๋ชป๋ ํฌ์ธํฐ ๊ฐ์ ๋ค์ํ ๋ฌธ์ ๋ฅผ ์ผ์ผํค๋ฉฐ, ํ ๋ฒ์ ์ค์๋ ํ๋ก๊ทธ๋จ์ ์ข ๋ฃ์ํด
- ๊ฒ์ ๊ท๋ชจ๊ฐ ์ปค์ง๊ณ ๊ตฌ์กฐ๊ฐ ๋ณต์กํด์ง์๋ก ํ๋ก๊ทธ๋๋จธ๊ฐ ์ค์ํ ํ๋ฅ ์ ํฌ๊ฒ ์ฆ๊ฐํ๋ค.
๐ C++ ์ดํ์ ๋์จ ์ธ์ด JAVA/C#์ ์ด๋ฐ ๊ณ ์ง์ ์ธ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํฌ์ธํฐ๋ฅผ ๋ฒ๋ฆฌ๊ณ ๊ฐ๋น์ง ์ปฌ๋ ์ ์์คํ ์ ๋์ ํจ
๐ ๊ฐ๋น์ง ์ปฌ๋ ์
- ํ๋ก๊ทธ๋จ์์ ๋ ์ด์ ์ฌ์ฉํ์ง ์๋ ์ค๋ธ์ ํธ๋ฅผ ์๋์ผ๋ก ๊ฐ์งํด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ํ๋ ์์คํ
- ๋์ ์ผ๋ก ์์ฑ๋ ๋ชจ๋ ์ค๋ธ์ ํธ ์ ๋ณด๋ฅผ ๋ชจ์๋ ์ ์ฅ์๋ฅผ ์ฌ์ฉํด ์ฌ์ฉ๋์ง ์๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ถ์
- ๋งํฌ-์ค์(Mark-Sweep) ๋ฐฉ์์ ๊ฐ๋น์ง ์ปฌ๋ ์
- ์ ์ฅ์์์ ์ต์ด ๊ฒ์์ ์์ํ๋ ๋ฃจํธ ์ค๋ธ์ ํธ๋ฅผ ํ๊ธฐํ๋ค.
- ๋ฃจํธ ์ค๋ธ์ ํธ๊ฐ ์ฐธ์กฐํ๋ ๊ฐ์ฒด๋ฅผ ์ฐพ์ ๋งํฌํ๋ค.
- ๋งํฌ๋ ๊ฐ์ฒด๋ก๋ถํฐ ๋ค์ ์ฐธ์กฐํ๋ ๊ฐ์ฒด๋ฅผ ์ฐพ์ ๋งํฌํ๊ณ ์ด๋ฅผ ๊ณ์ ๋ฐ๋ณตํ๋ค.
- ์ด์ ์ ์ฅ์์๋ ๋งํฌ๋ ๊ฐ์ฒด์ ๋งํฌ๋์ง ์์ ๊ฐ์ฒด์ ๋ ๊ทธ๋ฃน์ผ๋ก ๋๋๋ค.
- ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ์ ์ฅ์์์ ๋งํฌ๋์ง ์์ ๊ฐ์ฒด(๊ฐ๋น์ง)๋ค์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ํ๋ค(swee)
๐ฉ ์ธ๋ฆฌ์ผ ์์ง์ ๊ฐ๋น์ง ์ปฌ๋ ์ ์์คํ
- ๋งํฌ-์ค์ ๋ฐฉ์์ ๊ฐ๋น์ง ์ปฌ๋ ์ ์์คํ ์ ์์ฒด์ ์ผ๋ก ๊ตฌ์ถํจ
- ์ง์ ๋ ์ฃผ๊ธฐ๋ง๋ค ๋ชฐ์์ ์์ ๋๋ก ์ค์ ๋์ด ์์ (GCCycle, ๊ธฐ๋ณธ๊ฐ 60์ด)
- ์ฑ๋ฅ ํฅ์์ ์ํด ๋ณ๋ ฌ ์ฒ๋ฆฌ, ํด๋ฌ์คํฐ๋ง๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ํ์ฌํจ
๐ฉ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ ์ํ ๊ฐ์ฒด ์ ์ฅ์
- ๊ด๋ฆฌ๋๋ ๋ชจ๋ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๋ ์ ์ญ ๋ณ์ : GUObjectArray
- GUObjectArray์ ๊ฐ ์์์๋ ํ๋๊ทธ(Flag)๊ฐ ์ค์ ๋์ด ์์
- ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ์ฐธ๊ณ ํ๋ ์ฃผ์ ํ๋๊ทธ
- Garbage ํ๋๊ทธ : ๋ค๋ฅธ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ๋ก๋ถํฐ์ ์ฐธ์กฐ๊ฐ ์์ด ํ์ ์์ ์ธ ์ค๋ธ์ ํธ
- RootSet ํ๋๊ทธ : ๋ค๋ฅธ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ๋ก๋ถํฐ ์ฐธ์กฐ๊ฐ ์์ด๋ ํ์ํ์ง ์๋ ํน๋ณํ ์ค๋ธ์ ํธ
๊ฐ๋น์ง ์ปฌ๋ ํฐ๋ GUObjectArray์ ์๋ ํ๋๊ทธ๋ฅผ ํ์ธํด ๋น ๋ฅด๊ฒ ํ์ํด์ผ ํ ์ค๋ธ์ ํธ๋ฅผ ํ์ ํ๊ณ ๋ฉ๋ชจ๋ฆฌ์์ ์ ๊ฑฐํจ
๐ ๊ฐ๋น์ง ์ปฌ๋ ํฐ์ ๋ฉ๋ชจ๋ฆฌ ํ์
- ๊ฐ๋น์ง ์ปฌ๋ ํฐ๋ ์ง์ ๋ ์๊ฐ์ ๋ฐ๋ผ ์ฃผ๊ธฐ์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ํ๋ค (๊ธฐ๋ณธ ๊ฐ 60์ด)
- Garbage ํ๋๊ทธ๋ก ์ค์ ๋ ์ค๋ธ์ ํธ๋ฅผ ํ์ ํ๊ณ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์์ ํ๊ฒ ํ์ํจ
- Garbage ํ๋๊ทธ๋ ์๋์ผ๋ก ์ค์ ํ๋ ๊ฒ์ด ์๋, ์์คํ ์ด ์์์ ์ค์ ํจ
- ํ ๋ฒ ์์ฑ๋ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ๋ ๋ฐ๋ก ์ญ์ ๊ฐ ๋ถ๊ฐ๋ฅ (๋ ํผ๋ฐ์ค ์ ๋ณด๋ฅผ ์์ฐ์ผ๋ก์จ ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ์๋์ผ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ํ๋๋ก ํด์ผํ๋ค)
๐ ๋ฃจํธ์ ํ๋๊ทธ์ ์ค์
- AddToRoot ํจ์๋ฅผ ํธ์ถํด ๋ฃจํธ์ ํ๋๊ทธ๋ฅผ ์ค์ ํ๋ฉด ์ต์ด ํ์ ๋ชฉ๋ก์ผ๋ก ์ค์ ๋จ
- ๋ฃจํธ์ ์ผ๋ก ์ค์ ๋ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ๋ ๋ฉ๋ชจ๋ฆฌ ํ์๋ก๋ถํฐ ๋ณดํธ๋ฐ์
- RemoveFromRoot ํจ์๋ฅผ ํธ์ถํด ๋ฃจํธ์ ํ๋๊ทธ๋ฅผ ์ ๊ฑฐํ ์ ์์
- ์ฝํ ์ธ ๊ด๋ จ ์ค๋ธ์ ํธ์ ๋ฃจํธ์ ์ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ๊ถ์ฅ๋์ง ์์
๐ฉ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ๋ฅผ ํตํ ํฌ์ธํฐ ๋ฌธ์ ์ ํด๊ฒฐ
- ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฌธ์
- ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ๋ ๊ฐ๋น์ง ์ปฌ๋ ํฐ๋ฅผ ํตํด ์๋์ผ๋ก ํด๊ฒฐ
- C++ ์ค๋ธ์ ํธ๋ ์ง์ ์ ๊ฒฝ์จ์ผ ํจ(์ค๋งํธ ํฌ์ธํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํ์ฉ)
- ๋๊ธ๋ง ํฌ์ธํฐ ๋ฌธ์
- ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ๋ ์ด๋ฅผ ํ์งํ๊ธฐ ์ํ ํจ์๋ฅผ ์ ๊ณตํจ ::IsValid()
- C++ ์ค๋ธ์ ํธ๋ ์ง์ ์ ๊ฒฝ์จ์ผ ํจ(์ค๋งํธ ํฌ์ธํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ํ์ฉ)
- ์์ผ๋ ํฌ์ธํฐ ๋ฌธ์
- ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ์ UPROPERTY ์์ฑ์ ์ง์ ํ๋ฉด ์๋์ผ๋ก nullptr๋ก ์ด๊ธฐํ ํด์ค
- C++ ์ค๋ธ์ ํธ์ ํฌ์ธํฐ๋ ์ง์ nullptr๋ก ์ด๊ธฐํ ํ ๊ฒ (๋๋ ์ค๋งํธ ํฌ์ธํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํ์ฉ)
๐ฉ ํ์๋์ง ์๋ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ
- ์ธ๋ฆฌ์ผ ์์ง ๋ฐฉ์์ผ๋ก ์ฐธ์กฐ๋ฅผ ์ค์ ํ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ
- UPROPERTY๋ก ์ฐธ์กฐ๋ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ (๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ด๋ฅผ ์ฌ์ฉ)
- AddReferencedObject ํจ์๋ฅผ ํตํด ์ฐธ์กฐ๋ฅผ ์ค์ ํ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ
- ๋ฃจํธ์ (RootSet)์ผ๋ก ์ง์ ๋ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ
(์ค๋ธ์ ํธ ์ ์ธ์ ๊ธฐ๋ณธ์์น)
์ค๋ธ์ ํธ ํฌ์ธํฐ๋ ๊ฐ๊ธ์ UPROPERTY()๋ก ์ ์ธํ๊ณ , ๋ฉ๋ชจ๋ฆฌ๋ ๊ฐ๋น์ง์ปฌ๋ ํฐ๊ฐ ์๋์ผ๋ก ๊ด๋ฆฌํ๋๋ก ์์ํ๋ค.
๐ ์ผ๋ฐ ํด๋์ค์์ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒฝ์ฐ
- UPROPERTY๋ฅผ ์ฌ์ฉํ์ง ๋ชปํ๋ ์ผ๋ฐ C++ ํด๋์ค๊ฐ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ๋ฅผ ๊ด๋ฆฌํด์ผ ํ๋ ๊ฒฝ์ฐ
- FGCObject ํด๋์ค๋ฅผ ์์๋ฐ์ ํ AddReferencedObjects ํจ์๋ฅผ ๊ตฌํํ๋ค
- ํจ์ ๊ตฌํ๋ถ์์ ๊ด๋ฆฌํ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ๋ฅผ ์ถ๊ฐํด์ค
2. ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ์ ๊ด๋ฆฌ ์์น
- ์์ฑ๋ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ๋ฅผ ์ ์งํ๊ธฐ ์ํด ๋ ํผ๋ฐ์ค ์ฐธ์กฐ ๋ฐฉ๋ฒ์ ์ค๊ณํ ๊ฒ
- ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ ๋ด์ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ : UPROPERTY ์ฌ์ฉ
- ์ผ๋ฐ C++ ์ค๋ธ์ ํธ ๋ด์ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ : FGCObject์ ์์ ํ ๊ตฌํ
- ์์ฑ๋ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ๋๊ฐ์ ๋ก ์ง์ฐ๋ ค ํ์ง ๋ง ๊ฒ
- ์ฐธ์กฐ๋ฅผ ๋๋๋ค๋ ์๊ฐ์ผ๋ก ์ค๊ณํ ๊ฒ
- ๊ฐ๋น์ง ์ปฌ๋ ํฐ์๊ฒ ํ์๋ฅผ ์ฌ์ดํ ์๋ ์์ (ForceGarbageCollection ํจ์)
- ์ฝํ ์ธ ์ ์์์ Destroyํจ์๋ฅผ ์ฌ์ฉํ ์ ์์ผ๋, ๊ฒฐ๊ตญ ๋ด๋ถ ๋์์ ๋์ผํจ (๊ฐ๋น์ง ์ปฌ๋ ํฐ์ ์์)
๐ MyGameInstance(h, cpp)
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "MyGameInstance.generated.h"
/**
*
*/
UCLASS()
class UNREALMEMORY_API UMyGameInstance : public UGameInstance
{
GENERATED_BODY()
public:
virtual void Init() override;
virtual void Shutdown() override;
private:
TObjectPtr<class UStudent> NonPropStudent;
UPROPERTY()
TObjectPtr<class UStudent> PropStudent;
TArray<TObjectPtr<class UStudent>> NonPropStudents;
UPROPERTY()
TArray<TObjectPtr<class UStudent>> PropStudents;
class FStudentManager* StudentManager = nullptr;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyGameInstance.h"
#include "Student.h"
#include "StudentManager.h"
void CheckUObjectIsValid(const UObject* InObject, const FString& InTag) {
if (InObject->IsValidLowLevel()) {
UE_LOG(LogTemp, Log, TEXT("[%s] ์ ํจํ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ"), *InTag);
}
else {
UE_LOG(LogTemp, Log, TEXT("[%s] ์ ํจํ์ง ์์ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ"), *InTag);
}
}
void CheckUObjectIsNull(const UObject* InObject, const FString& InTag) {
if (nullptr == InObject) {
UE_LOG(LogTemp, Log, TEXT("[%s] ๋ ํฌ์ธํฐ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ"), *InTag);
}
else {
UE_LOG(LogTemp, Log, TEXT("[%s] ๋ ํฌ์ธํฐ๊ฐ ์๋ ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ"), *InTag);
}
}
void UMyGameInstance::Init()
{
Super::Init();
NonPropStudent = NewObject<UStudent>();
PropStudent = NewObject<UStudent>();
NonPropStudents.Add(NewObject<UStudent>());
PropStudents.Add(NewObject<UStudent>());
StudentManager = new FStudentManager(NewObject<UStudent>());
}
void UMyGameInstance::Shutdown()
{
Super::Shutdown();
const UStudent* StudentInManager = StudentManager->GetStudent();
delete StudentManager;
StudentManager = nullptr;
CheckUObjectIsNull(StudentInManager, TEXT("StudentInManager"));
CheckUObjectIsValid(StudentInManager, TEXT("StudentInManager"));
CheckUObjectIsNull(NonPropStudent, TEXT("NonPropStudent"));
CheckUObjectIsValid(NonPropStudent, TEXT("NonPropStudent"));
CheckUObjectIsNull(PropStudent, TEXT("PropStudent"));
CheckUObjectIsValid(PropStudent, TEXT("PropStudent"));
CheckUObjectIsNull(NonPropStudents[0], TEXT("NonPropStudents"));
CheckUObjectIsValid(NonPropStudents[0], TEXT("NonPropStudents"));
CheckUObjectIsNull(PropStudents[0], TEXT("PropStudents"));
CheckUObjectIsValid(PropStudents[0], TEXT("PropStudents"));
}
๐ StudentManager (h, cpp)
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
/**
*
*/
class UNREALMEMORY_API FStudentManager : public FGCObject
{
public:
FStudentManager(class UStudent* InStudent) : SafeStudent(InStudent) {}
// FGCObject๋ฅผ ์์๋ฐ์ ๋ ๊ตฌํํด์ผ ํ๋ ํจ์1
virtual void AddReferencedObjects(FReferenceCollector& Collector) override;
// FGCObject๋ฅผ ์์๋ฐ์ ๋ ๊ตฌํํด์ผ ํ๋ ํจ์2
virtual FString GetReferencerName() const override {
return TEXT("FStudentManager");
}
const class UStudent* GetStudent() const { return SafeStudent; }
private:
class UStudent* SafeStudent = nullptr;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "StudentManager.h"
#include "Student.h"
void FStudentManager::AddReferencedObjects(FReferenceCollector& Collector)
{
if (SafeStudent->IsValidLowLevel()) {
Collector.AddReferencedObject(SafeStudent);
}
}
'โ๏ธ ์์ง > ๐ซ ์ธ๋ฆฌ์ผ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Unreal] ์ธ๋ฆฌ์ผ ์ค๋ธ์ ํธ ๊ด๋ฆฌ1 - ์ง๋ ฌํ (0) | 2024.05.08 |
---|---|
[Unreal] ์์ํด์ ์ธ๋ฆฌ์ผ 2024 - 1. ๋ ๋ฒจ ์ ์ํ๊ธฐ (0) | 2024.05.05 |
[Unreal] ์ธ๋ฆฌ์ผ ์ปจํ ์ด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ2 - ๊ตฌ์กฐ์ฒด์ TMap (0) | 2024.05.04 |
[Unreal] ์ธ๋ฆฌ์ผ ์ปจํ ์ด๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ1 - Array์ Set (0) | 2024.05.04 |
[Unreal] ๋ธ๋ฆฌ๊ฒ์ดํธ (0) | 2024.05.04 |