์–ธ๋ฆฌ์–ผ ์˜ค๋ธŒ์ ํŠธ ํฌ์ธํ„ฐ๋Š” C++์˜ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์™€ ์ „ํ˜€ ๋‹ค๋ฆ„


UPROPERTY ๋งˆํ‚น๋œ raw pointer๋Š” C++ ๋ฌธ๋ฒ•์ƒ unmanaged์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์–ธ๋ฆฌ์–ผ GC๊ฐ€ ์ถ”์ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— strong reference์ž„

UPROPERTY ๋งˆํ‚น๋˜์ง€ ์•Š์€ raw pointer๋Š” ์–ธ๋ฆฌ์–ผ ํ”„๋กœํผํ‹ฐ ์‹œ์Šคํ…œ(๋ฆฌํ”Œ๋ ‰์…˜)์— ๋ณด์ด์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— GC๊ฐ€ ์ถ”์ ํ•  ์ˆ˜ ์—†์Œ


๋ณดํ†ต GC๋Š” ๋ชจ๋“  ์˜ค๋ธŒ์ ํŠธ์— ๋Œ€ํ•ด ์ฐธ์กฐ๊ด€๊ณ„๋ฅผ ๊ทธ๋ž˜ํ”„๋กœ ๊ทธ๋ ค์„œ reachability(๋„๋‹ฌ์„ฑ)๋ฅผ ์ถ”์ ํ•จ

๊ทธ๋Ÿฌ๋‹ค๊ฐ€ ์–ด๋–ค ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๋” ์ด์ƒ ์ฐธ์กฐ๋˜์ง€ ์•Š์•„ unreachable(orphaned)์ด๋ผ๊ณ  ํŒ๋‹จ๋˜๋ฉด ์‚ญ์ œํ•˜๋Š” ์‹์œผ๋กœ ๋™์ž‘ํ•จ

์‰ฝ๊ฒŒ ๋งํ•ด์„œ ์•„๋ฌด๋„ ์ฐธ์กฐํ•˜์ง€ ์•Š์œผ๋ฉด ์‚ญ์ œํ•˜๋Š”๊ฑฐ์ž„. ๋ญ ์ด๊ฑด ์ด๋ฏธ ์•Œ๊ณ  ์žˆ๊ฒ ์ง€๋งŒ..


๊ทธ๋Ÿฌ๋‚˜ ์–ธ๋ฆฌ์–ผ์˜ ๊ฐ€๋น„์ง€ ์ฝœ๋ ‰ํ„ฐ์—๋Š” MarkPendingKill ์ด๋ผ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ๋Š”๋ฐ, reachable object๋ผ๋„ ๊ฐ•์ œ๋กœ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์ž„

๊ทธ๋Ÿผ ํ•ด๋‹น object์— ๋Œ€ํ•œ strong references๋Š” ์–ด๋–ป๊ฒŒ ๋˜๋Š”๊ฑฐ๋ƒ?


a04424ad2c06782ab47e5a67ee91766dc289f1ecd1acc5cfbf10d4c052d3d42194780023d3e5e0816545e00a92ba


GC๊ฐ€ ํ•ด๋‹น reference(pointer)๋ฅผ ์ž๋™์œผ๋กœ null๋กœ ๋ฐ”๊ฟ”์คŒ

๋•๋ถ„์— ๊ฐ•์ œ ์‚ญ์ œ๋˜๋”๋ผ๋„ dangling pointer๊ฐ€ ๋˜๋Š” ์ผ์ด ์—†์–ด ์•ˆ์ „ํ•จ

๊ฐ€์žฅ ํ”ํ•œ ์˜ˆ์‹œ๊ฐ€ ์œ„ ๋ฌธ์„œ์—๋„ ์จ์žˆ๋“ฏ์ด AActor::Destroy() ๊ฐ™์€ ๊ธฐ๋Šฅ์ž„

์•กํ„ฐ๋Š” ๊ฒŒ์ž„ ์ค‘๊ฐ„์— ์–ธ์ œ๋“  ์‚ญ์ œ๋  ์ˆ˜ ์žˆ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ๊ธฐ๋Šฅ์ด ์žˆ๋Š” ๊ฒƒ์ž„


UObejct์— ๋Œ€ํ•œ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ UObject๊ฐ€ ์•„๋‹Œ Native C++์—์„œ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด...

์ด ๊ฒฝ์šฐ ๋ฆฌํ”Œ๋ ‰์…˜ ์‹œ์Šคํ…œ์ด ๋ชป๋ณด๊ธฐ ๋•Œ๋ฌธ์— strong ref๊ฐ€ ๋  ์ˆ˜ ์—†๋‹ค (์ฐธ์กฐ์ค‘์ธ UObject์— ๋Œ€ํ•ด reachableํ•œ ๊ฒƒ์œผ๋กœ ์ธ์ •๋ฐ›์ง€ ๋ชปํ•จ)

๋”ฐ๋ผ์„œ ํ•ด๋‹น UObject๊ฐ€ unreachable์ด ๋˜์–ด GC์— ์˜ํ•ด ์‚ญ์ œ๋˜๋Š” ๊ฒƒ์„ ๋ง‰์„ ์ˆ˜๋„ ์—†๊ณ , GC๊ฐ€ ํ•ด๋‹น reference๋ฅผ ์ž๋™์œผ๋กœ null๋กœ ๋งŒ๋“ค์–ด์ฃผ์ง€๋„ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์‚ญ์ œ๋˜์—ˆ๋‹ค๋Š” ์‚ฌ์‹ค์กฐ์ฐจ๋„ ์•Œ ์ˆ˜๊ฐ€ ์—†์–ด ์œ„ํ—˜ํ•˜๋‹ค


์ด๋Ÿฐ ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด์„œ TWeakObjectPtr์ด ์žˆ์Œ. ์‚ญ์ œ๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ผ๋„ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์นœ๊ตฌ์ž„

์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์˜ TWeakPtr๊ณผ๋Š” ๋น„์Šทํ•œ๊ฒƒ ๊ฐ™์œผ๋ฉด์„œ๋„ ์ „ํ˜€ ๋‹ค๋ฅธ ๋…€์„์ด๋‹ˆ ํ—ท๊ฐˆ๋ฆฌ์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•˜์…ˆ


์ฐธ๊ณ ๋กœ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ๋„ ๋‚ด๋ถ€์ ์œผ๋กœ UObject๋ฅผ TWeakObjectPtr๋กœ ์ฐธ์กฐํ•˜๋„๋ก ๊ตฌํ˜„๋˜์–ด์žˆ์Œ

๊ทธ๋ž˜์„œ BindUObject ํ•จ์ˆ˜๊ฐ€ ๋”ฐ๋กœ ์žˆ๋Š”๊ฑฐ์ž„

์‚ญ์ œ๋œ UObject์— ๋Œ€๊ณ  ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ์‹คํ–‰์‹œ์ผฐ๋‹ค๊ฐ„ ํฐ์ผ๋‚˜๋‹ˆ๊นŒ ์ ์–ด๋„ ๋“ฑ๋ก ๋Œ€์ƒ์ด ์‚ด์•„์žˆ๋Š”์ง€๋Š” ์•Œ์ˆ˜์žˆ์–ด์•ผ์ง€


์ฝ”๋“œ๋กœ ์ •๋ฆฌํ•˜๋ฉด


UCLASS(...)

class UMyObject : public UObject

{

GENERATED_BODY()


UPROPERTY()

UAnotherMyObject* StrongRef; // GC๊ฐ€ ์ถ”์ ํ•ด์„œ ๊ด€๋ฆฌํ•ด์คŒ. ์ฐธ์กฐ ๋Œ€์ƒ์— ๋Œ€ํ•ด ์†Œ์œ ๊ถŒ ์žˆ์Œ


TWeakObjectPtr<UAnotherMyObject> WeakRef; // GC๊ฐ€ ์ถ”์ ํ•˜์ง€๋Š” ์•Š์Œ. ์†Œ์œ ๊ถŒ์€ ์—†์ง€๋งŒ ์‚ด์•„์žˆ๋Š”์ง€ ์กฐํšŒํ•ด๋ณผ์ˆ˜๋Š” ์žˆ์Œ


UAnotherMyObject* UnmanagedRef; // ์œ„ํ—˜ํ•จ. ์†Œ์œ ๊ถŒ๋„ ์—†๊ณ  ์‚ด์•„์žˆ๋Š”์ง€๋„ ์•Œ์ˆ˜์—†์Œ


TWeakPtr<FMyData> WeakPtr; // ์ „ํ˜€ ๋‹ค๋ฅธ ๋†ˆ. UObject๋ž‘ ๊ด€๋ จ ์—†์Œ (native c++)

...

};


์ด์ƒ์ด ์–ธ๋ฆฌ์–ผ์˜ ์˜ค๋ธŒ์ ํŠธ ์ฒ˜๋ฆฌ์™€ ๊ฐ€๋น„์ง€ ์ฝœ๋ ‰ํ„ฐ์— ๊ด€ํ•œ ๋‚ด์šฉ์ด๊ณ 

์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์™€ ํ”ํžˆ ํ˜ผ๋™ํ•˜๋Š” ๋ถ€๋ถ„์„ ์ •๋ฆฌํ•ด์ฃผ์ž๋ฉด



C++์—์„œ stack ๊ฐ์ฒด์˜ storage class๋Š” automatic storage duration์ž„

์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ์–ธ์–ด์  ๊ฐœ๋…์ธ '์Šค์ฝ”ํ”„ { } ๋‚ด๋ถ€' ๋ผ๊ณ  ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜๋จ

์ƒ๋ช…์ฃผ๊ธฐ๊ฐ€ ๋ช…ํ™•ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹ฌ์ง€์–ด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๋„ ์†Œ๋ฉธ์ž๋Š” ๋ฐ˜๋“œ์‹œ ํ˜ธ์ถœ๋œ๋‹ค๋Š” ๊ฒƒ์ด ๋ณด์žฅ๋จ


๊ทธ๋ž˜์„œ ์†Œ๋ฉธ์ž๋ฅผ ์ด์šฉํ•˜๋ฉด ๋™์ (heap) ๊ฐ์ฒด์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋„ ์•ˆ์ „ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์ง€ ์•Š๊ฒ ๋ƒ๋Š” ์•„์ด๋””์–ด์—์„œ ๋‚˜์˜จ๊ฒŒ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ์ž„

์ƒ์„ฑ์ž/์†Œ๋ฉธ์ž๋ฅผ ์ด์šฉํ•ด์„œ ํฌ์ธํ„ฐ '์Šค์Šค๋กœ' ์ฐธ์กฐ ํšŸ์ˆ˜๋ฅผ ์„ธ๋„๋ก ํ•˜๋Š”๊ฑฐ์ž„. ๊ทธ๋ž˜์„œ ์Šค๋งˆํŠธ ๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฒƒ


ํฌ์ธํ„ฐ ์Šค์Šค๋กœ ์ฐธ์กฐ ํšŸ์ˆ˜๋ฅผ ์„ผ๋‹ค๋Š” ๋ถ€๋ถ„์ด ์ค‘์š”ํ•จ

์Šค๋งˆํŠธ ํฌ์ธํ„ฐ ์Šค์Šค๋กœ ์ง์ ‘ ํŒ๋‹จํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ฐธ์กฐ๊ด€๊ณ„๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” '์ฆ‰์‹œ' ๋ ˆํผ๋Ÿฐ์Šค ์นด์šดํŠธ๋ฅผ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ์Œ

๊ทธ๋ž˜์„œ ์Šค๋งˆํŠธ ํฌ์ธํ„ฐ๋กœ ๊ด€๋ฆฌ๋˜๋Š” ์˜ค๋ธŒ์ ํŠธ๋Š” orphaned(๊ณ ์•„)๊ฐ€ ์—†์Œ. ๊ณ ์•„๊ฐ€ ๋˜๋Š” ์ฆ‰์‹œ ๋ฐ”๋กœ ์‚ญ์ œํ•˜๋‹ˆ๊นŒ.



๋ฐ˜๋ฉด GC ๋ฐฉ์‹์€ GC๋ผ๋Š” ์™ธ๋ถ€ ์‹œ์Šคํ…œ์ด ์ฐธ์กฐ๊ด€๊ณ„๋ฅผ '๋А๊ธ‹ํ•˜๊ฒŒ' ์ถ”์ ํ•จ

๋„๋‹ฌ์„ฑ ๊ณ„์‚ฐ์ด ์ •ํ•ด์ง„ ์ฃผ๊ธฐ์— ๋”ฐ๋ผ ์ˆ˜ํ–‰๋จ


void foo()

{

UMyObject* Obj = NewObject<UMyObject>();

...

}


์ด๋ ‡๊ฒŒ NewObject๋กœ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋ฅผ raw pointer์— ๋‹ด์•„๋„ ๋ฐ”๋กœ ์‚ญ์ œ๋˜์ง€ ์•Š๋Š”๊ฑด ์ด๋Ÿฐ ์ด์œ  ๋•Œ๋ฌธ์ž„

ํ•˜์ง€๋งŒ ์ €๋ ‡๊ฒŒ ์ƒ์„ฑํ•œ ๊ฐ์ฒด๋ฅผ strong ref๋กœ ๋‹ด์•„๋‘์ง€ ์•Š์œผ๋ฉด ์กฐ๋งŒ๊ฐ„ ์‚ญ์ œ๋˜๊ณ  ๋ง๊ฒ ์ง€



๋งˆ์ง€๋ง‰์œผ๋กœ, ์งˆ๋ฌธ์ž๊ฐ€ ์˜ฌ๋ฆฐ ์ฝ”๋“œ ์Šค๋‹ˆํŽซ์— ์˜ค๋ฅ˜๊ฐ€ ์žˆ๊ธธ๋ž˜ ์„ค๋ช…์งค๋กœ ๋งˆ๋ฌด๋ฆฌํ•จ


7ceb8472b78069f139ee98bf06d60403aa348e690a764725ef1d