Abstract
๋ ํผ๋ฐ์ค ํ์ ์ฝ์ด์์ ๊ฒ์ ์ฝ๋๊ฐ ๊ฐ์ฅ ์์ฃผ ์ง์ ๋ถ๋ฅด๋ ํด๋์ค์
๋๋ค. new ๋ก ๋ง๋ค๊ณ ๋ฒ๋ฆฌ๋ ์์ ๊ฐ์ฒด๋ฅผ Acquire ๋ก ๊บผ๋ด๊ณ Release ๋ก ๋๋ ค๋๊ฒ ํด์, ํ๋ ์ด ์ค ๊ฐ๋น์ง๊ฐ ์์ด์ง ์๊ฒ ํฉ๋๋ค. ์ด ํ์ด์ง๋ ๊ทธ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ, Unity ์ชฝ
Reference Pooling (๋ ํผ๋ฐ์ค ํ๋ง) ํ์ด์ง๋ ์์ ๊ฒ์์์์ ์ฌ์ฉ ํจํด์ ๋ค๋ฃน๋๋ค.
์ new ๊ฐ ๋ฌธ์ ์ธ๊ฐ
๋ฑ์๋ผ์ดํฌ์์ ์ ์ด ์ด๋น 5๋ง๋ฆฌ ์ฃฝ๊ณ , ๊ทธ๋๋ง๋ค ์ด๋ฒคํธ ์ธ์ ํ๋์ ์ํฐํฐ ๋ฐ์ดํฐ ํ๋๊ฐ ๋ง๋ค์ด์ง๋ค๊ณ ํฉ์๋ค. 1๋ถ์ด๋ฉด 600๊ฐ์ ๊ฐ์ฒด๊ฐ ๋ฒ๋ ค์ง๋๋ค. C# ์ ๊ฐ๋น์ง ์ปฌ๋ ํฐ๋ ์ด๊ฒ๋ค์ ์น์ธ ๋ ๊ฒ์์ ์ ๊น ๋ฉ์ถฅ๋๋ค. ๋ชจ๋ฐ์ผ์์๋ ์ด ๋ฉ์ถค์ด ๋์ ๋ณด์ด๋ ๋๊น์ด ๋ฉ๋๋ค. ํ์ ์ฐ๋ฉด ๊ฐ์ ๊ฐ์ฒด ๋ช ๊ฐ๊ฐ ๊ณ์ ๋๊ธฐ ๋๋ฌธ์ ์น์ธ ๊ฒ์ด ์๊ธฐ์ง ์์ต๋๋ค.
๋ด๋ถ ๊ตฌ์กฐ๋ ๋จ์ํ๋ค
graph LR
A["Acquire<T>()"] --> B{"T ํ์
ํ์<br>๋จ์ ๊ฒ์ด ์๋"}
B -- ์๋ค --> C["๊บผ๋ด์ ๋ฐํ"]
B -- ์๋ค --> D["new T() ๋ก ์์ฑ"]
E["Release(obj)"] --> F["obj.Clear()"] --> G["T ํ์
ํ์ ๋ฃ๊ธฐ"]Mermaid
๋ณต์ฌ
ํ์
๋ง๋ค ํ๊ฐ ํ๋์ฉ ์์ ๋ฟ์
๋๋ค. ํฌ๊ธฐ ์ ํ๋, ๋ง๋ฃ ์๊ฐ๋ ์์ต๋๋ค. ๊ทธ๋์ ํ ๋ฒ ์ต๋์น๊น์ง ๋์ด๋ ํ์ ์ค์ด๋ค์ง ์์ต๋๋ค โ ์ค์ด๋ ค๋ฉด Remove<T>(count) ๋ RemoveAll<T>() ๋ฅผ ์ง์ ๋ถ๋ฌ์ผ ํฉ๋๋ค.
์ค๋ธ์ ํธ ํ๊ณผ ๋ฌด์์ด ๋ค๋ฅธ๊ฐ
๋ ํผ๋ฐ์ค ํ | ์ค๋ธ์ ํธ ํ | |
๋์ | ์์ C# ๊ฐ์ฒด | ๋ฌด์์ด๋ (์ฃผ๋ก GameObject, ์์
) |
์ ๊ทผ | ์ ์ ํด๋์ค. ์ด๋์๋ ๋ฐ๋ก | ๋ชจ๋. ํ์ ๋จผ์ ๋ง๋ค์ด์ผ ํ๋ค |
์ฉ๋ยท๋ง๋ฃ | ์์ | ์์ (Capacity, Expire Time) |
์ด๊ธฐํ ์ฑ
์ | Clear() ํ ๊ณณ | OnSpawn / OnUnspawn / Release |
ํ์ฅ โ ๋ฏธ๋ฆฌ ์ฑ์ ๋๊ธฐ
์ ํฌ๊ฐ ์์๋๋ ์๊ฐ ํ๊บผ๋ฒ์ ๊ฐ์ฒด๊ฐ ๋ง๋ค์ด์ ธ ๋๊ธฐ๋ ๊ฒ์ด ๋ณด์ธ๋ค๋ฉด, ๋ก๋ฉ ํ๋ฉด์์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด ๋ ์ ์์ต๋๋ค.
private const int PrewarmEnemyDataCount = 16;
// ๋ก๋ฉ Procedure ์์
ReferencePool.Add<EnemyData>(PrewarmEnemyDataCount);
C#
๋ณต์ฌ
๋ณธ๋ฌธ์ ์ฝ์ ๋ ์ฃผ์ํ ์
โข
๋ณธ๋ฌธ ์์ ๋ GameFrameworkEventArgs ๋ฅผ ์์ํฉ๋๋ค. ์ด๊ฒ์ ํ๋ ์์ํฌ ๋ด๋ถ C# ์ด๋ฒคํธ์ ์ธ์์ฉ ๊ธฐ๋ฐ ํด๋์ค์
๋๋ค. ๊ฒ์ ์ฝ๋๊ฐ EventComponent ๋ก ์ฃผ๊ณ ๋ฐ๋ ์ด๋ฒคํธ๋ GameEventArgs ๋ฅผ ์์ํด์ผ ํ๊ณ , Id ํ๋กํผํฐ๋ ๊ตฌํํด์ผ ํฉ๋๋ค.
โข
ReferencePool.EnableStrictCheck = true; ๋ฅผ ์ฝ๋์์ ์ง์ ์ธ ์ผ์ ์์ต๋๋ค. Unity ์ชฝ ReferencePoolComponent ๊ฐ ์ธ์คํํฐ ์ค์ ์ ๋ฐ๋ผ ์ผ ์ค๋๋ค.
โข
์ด์ค ๋ฐ๋ฉ์ Strict Check ๊ฐ ์ผ์ ธ ์์ ๋๋ง ์์ธ๋ก ์กํ๋๋ค. ๊บผ์ ธ ์์ผ๋ฉด ๊ฐ์ ๊ฐ์ฒด๊ฐ ํ์ ๋ ๋ฒ ๋ค์ด๊ฐ, ์ดํ ์๋ก ๋ค๋ฅธ ๋ ๊ณณ์ด ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๋ฐ๋ ์ฐพ๊ธฐ ์ด๋ ค์ด ๋ฒ๊ทธ๊ฐ ๋ฉ๋๋ค. ๊ฐ๋ฐ ์ค์๋ ๋ฐ๋์ ์ผ ๋์ธ์.
โข
"์ค๋ ๋ ์์ "์ ๋ง์ต๋๋ค(๋ด๋ถ์์ lock ์ ๊ฒ๋๋ค). ๋ค๋ง ํ์์ ๊บผ๋ธ ๊ฐ์ฒด ์์ฒด๋ฅผ ์ฌ๋ฌ ์ค๋ ๋๊ฐ ๊ฐ์ด ์ฐ๋ ๊ฒ๊น์ง ๋ณดํธํด ์ฃผ์ง๋ ์์ต๋๋ค.
Reference Pool
๊ด๋ จ ์์ค ํ์ผ (Relevant source files)
โข
GameFramework/Base/EventPool/BaseEventArgs.cs
โข
GameFramework/Base/GameFrameworkEventArgs.cs
โข
GameFramework/Base/ReferencePool/IReference.cs
โข
GameFramework/Base/ReferencePool/ReferencePool.ReferenceCollection.cs
โข
GameFramework/Base/ReferencePool/ReferencePool.cs
โข
GameFramework/Base/ReferencePool/ReferencePoolInfo.cs
โข
GameFramework/Sound/ResetSoundAgentEventArgs.cs
๋ชฉ์ ๊ณผ ๊ฐ์ (Purpose and Overview)
Reference Pool์ ๊ฐ์ฒด๋ฅผ ๋งค๋ฒ ์๋ก ๋ง๋ค๊ณ ํ๊ดดํ๋ ๋์ ์ฌ์ฌ์ฉํด์ ๊ฐ๋น์ง ์ปฌ๋ ์
(GC) ๋ถํ๋ฅผ ์ค์ด๋ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ์์คํ
์
๋๋ค. ์ด๋ฒคํธ ์ธ์ ๊ฐ์ ๋น๋ฒํ ์์ฑ๋๋ ์์ ๊ฐ์ฒด์์ ํนํ ํจ๊ณผ์ ์ด๋ฉฐ, ๊ณผ๋ํ GC๋ก ์ธํ ์ฑ๋ฅ ์ ํ๋ฅผ ๋ง์์ค๋๋ค.
Reference Pool์ GameFramework์ ์ฝ์ด ์ปดํฌ๋ํธ ์ค ํ๋์ด๋ฉฐ, Object Pool Manager(์ค๋ธ์ ํธ ํ)์ ํจ๊ป ์ฐ์ผ ์ ์์ง๋ง ์ด์ ์ด ๋ค๋ฆ
๋๋ค(Reference Pool์ ์๊ณ ์งง๊ฒ ์ฌ๋ ๊ฐ์ฒด ์์ฃผ).
ํต์ฌ ๊ตฌ์ฑ์์ (Core Components)
ReferencePool
์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฐ์ฒด ๋ชจ์์ ๊ด๋ฆฌํ๋ ์ ์ ํด๋์ค.
โข
ํ์
์ ํค๋ก ํ๋ ReferenceCollection ์ฌ์ ์ ์ ์ง
โข
๊ฐ์ฒด ํ๋/๋ฐ๋ฉ ๋ฐ ํ ๊ด๋ฆฌ API ์ ๊ณต
โข
์ฌ๋ฐ๋ฅธ ์ฌ์ฉ์ ๊ฐ์ ํ๋ ์๊ฒฉ ๊ฒ์ฌ(Strict Check) ๋ชจ๋ ์ ๊ณต
IReference
ํ์ ๋ฃ์ ์ ์๋ ๋ชจ๋ ๊ฐ์ฒด๊ฐ ๊ตฌํํด์ผ ํ๋ ์ธํฐํ์ด์ค.
โข
๋ฐ๋ฉ ์ ์ํ๋ฅผ ์ด๊ธฐํํ๊ธฐ ์ํ Clear() ๋ฉ์๋ ์ ์
ReferenceCollection
ํน์ ํ์
์ ์ฐธ์กฐ๋ฅผ ๊ด๋ฆฌํ๋ ๋ด๋ถ ํด๋์ค.
โข
๋ฏธ์ฌ์ฉ ์ฐธ์กฐ๋ค์ ํ ๋ณด๊ด
โข
ํ๋/๋ฐ๋ฉ/์ถ๊ฐ/์ ๊ฑฐ ๋ฑ ์ฌ์ฉ ํต๊ณ ๊ธฐ๋ก
โข
ํ์ด ๋น๋ฉด ์ ์ธ์คํด์ค ์์ฑ ์ฒ๋ฆฌ
ReferencePoolInfo
ํน์ ์ฐธ์กฐ ํ์ ์ ๋ณด๋ฅผ ๋ด๋ ๊ตฌ์กฐ์ฒด.
โข
๋ชจ๋ํฐ๋ง/๋๋ฒ๊น
์ ์ ์ฉํ ์ฌ์ฉ ํต๊ณ ์ ๊ณต
GameFrameworkEventArgs
์ด๋ฒคํธ ์ธ์์ ์ถ์ ๊ธฐ๋ณธ ํด๋์ค์ด์ IReference ๊ตฌํ์ฒด.
โข
์ด๋ฒคํธ ์ธ์๋ ์์ฃผ ๋ง๋ค์ด์ก๋ค๊ฐ ๋ฒ๋ ค์ง๋ฏ๋ก ํ๋ง์ ๋ํ์ ์ธ ๋์
๋์ ๋ฐฉ์ (How Reference Pooling Works)
ํ๋(Acquisition)
ํด๋ผ์ด์ธํธ๊ฐ ์ฐธ์กฐ๊ฐ ํ์ํ๋ฉด ReferencePool.Acquire<T>() ํธ์ถ:
โข
ํ์ด ๋น์ด ์์ง ์์ผ๋ฉด ํ๋ ๊บผ๋ด ๋ฐํ
โข
๋น์ด ์์ผ๋ฉด ์ ์ธ์คํด์ค ์์ฑ
โข
ํต๊ณ ์นด์ดํฐ ์
๋ฐ์ดํธ
์ฌ์ฉ(Usage)
๋ฐํ๋ฐ์ ๊ฐ์ฒด๋ฅผ ํ์ํ ๋์ ์ฌ์ฉ.
๋ฐ๋ฉ(Release)
์ฌ์ฉ์ ๋๋ด๋ฉด ReferencePool.Release(reference) ํธ์ถ:
โข
๊ฐ์ฒด์ Clear()๋ฅผ ํธ์ถํ์ฌ ์ํ ์ด๊ธฐํ
โข
ํด๋น ํ์
์ ์ปฌ๋ ์
ํ์ ์ฌ๋ฑ๋ก
โข
ํต๊ณ ์นด์ดํฐ ์
๋ฐ์ดํธ
์๊ฒฉ ๊ฒ์ฌ(Strict Checking)
๊ฐ๋ฐ ์ค ์ค๋จ์ฉ์ ์ก๊ธฐ ์ํ ๊ฒ์ฌ๋ฅผ ํ์ฑํํ ์ ์์:
โข
์ ํจํ ํ์
์ธ์ง(์ถ์ X, IReference ๊ตฌํ) ํ์ธ
โข
์ค๋ณต ๋ฐ๋ฉ ๊ฐ์ ์ค๋ฅ ๊ฒ์ฌ
GameFramework์์ ์ฐ๋ (Integration)
์ด๋ฒคํธ ์์คํ
โข
๋๋ถ๋ถ์ ์ด๋ฒคํธ ์ธ์ ํด๋์ค๋ GameFrameworkEventArgs๋ฅผ ์์(IReference ๊ตฌํ)
โข
์์ฃผ ์์ฑยท์๋ฉธ๋๋ ์ด๋ฒคํธ ์ธ์๊ฐ ํ๋ง์ ์ต์ ๋์
โข
์: ResetSoundAgentEventArgs.Create() ๋ด๋ถ์์ ReferencePool.Acquire<ResetSoundAgentEventArgs>() ์ฌ์ฉ
ํ๋ ์์ํฌ ์ปดํฌ๋ํธ
โข
Entity/UI/Sound/Network ๋ฑ ์ฌ๋ฌ ๋งค๋์ ๊ฐ ์ด๋ฒคํธ ์์คํ
์ ๊ด๋ฒ์ํ๊ฒ ์ฌ์ฉ
โข
์ด๋ก ์ธํด Reference Pool์ GC ์ ๊ฐ ํจ๊ณผ๋ฅผ ๊ฐ์ ์ ์ผ๋ก ํฌ๊ฒ ์ป์
์ฝ์ด ์ธํ๋ผ
โข
Reference Pool์ GameFrameworkEntry์ ๋๋ํ ์์นํ ์ฝ์ด ์ธํ๋ผ๋ก,
๋ชจ๋ ๋ชจ๋๊ณผ ๊ฒ์ ์ฝ๋์์ ๊ณต์ฉ์ผ๋ก ์ฌ์ฉํ ์ ์์
์ฌ์ฉ ํจํด (Usage Patterns)
ํ๋ง ๊ฐ๋ฅํ ํด๋์ค ๋ง๋ค๊ธฐ
IReference๋ฅผ ๊ตฌํ(๋ณดํต GameFrameworkEventArgs ์์)ํ๊ณ Clear()๋ก ์ด๊ธฐํ:
public class MyCustomEventArgs : GameFrameworkEventArgs
{
private int m_Value;
public int Value => m_Value;
public static MyCustomEventArgs Create(int value)
{
MyCustomEventArgs eventArgs = ReferencePool.Acquire<MyCustomEventArgs>();
eventArgs.m_Value = value;
return eventArgs;
}
public override void Clear()
{
m_Value = 0;
}
}
C#
๋ณต์ฌ
์ ํ์ ์ธ ํ๋ฆ
// 1) ํ๋
MyCustomEventArgs args = ReferencePool.Acquire<MyCustomEventArgs>();
// ๋๋ ํฉํ ๋ฆฌ ๋ฉ์๋
MyCustomEventArgs args2 = MyCustomEventArgs.Create(42);
// 2) ์ฌ์ฉ
// ... args ์ฌ์ฉ ...
// 3) ๋ฐ๋ฉ
ReferencePool.Release(args);
C#
๋ณต์ฌ
ํ ๊ด๋ฆฌ API (์์)
โข
Add<T>(count) : ์ง์ ๊ฐ์๋งํผ ๋ฏธ๋ฆฌ ์์ฑํด ํ์ ์ถ๊ฐ
โข
Remove<T>(count) : ์ง์ ๊ฐ์๋งํผ ์ ๊ฑฐ
โข
RemoveAll<T>() : ํด๋น ํ์
์ ๋ถ ์ ๊ฑฐ
โข
ClearAll() : ๋ชจ๋ ์ฐธ์กฐ ํ ์ด๊ธฐํ
โข
GetAllReferencePoolInfos() : ๋ชจ๋ ํ์ ํต๊ณ ์ ๋ณด ์กฐํ
์ฑ๋ฅ ๊ด์ (Performance Considerations)
์ด์
โข
GC ๊ฐ์: ์ฌ์ฌ์ฉ์ผ๋ก GC ๋น๋/์ ์ง ์๊ฐ์ ์ค์
โข
๋ฉ๋ชจ๋ฆฌ ํจ์จ: ์์ฃผ ์ฐ๋ ์์ ๊ฐ์ฒด๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ ์งํ์ฌ ๋ฐ๋ณต ํ ๋น ํํผ
โข
์ฑ๋ฅ ํฅ์: ์ด๋ฒคํธ๊ฐ ๋ง๊ฑฐ๋ ์์ ๊ฐ์ฒด๊ฐ ๋ง์ ์์คํ
์์ ํนํ ํจ๊ณผ์
๋ฒ ์คํธ ํ๋ํฐ์ค
โข
์์ ์ด๊ธฐํ: Clear()์์ ๋ชจ๋ ํ๋๋ฅผ ๊ผผ๊ผผํ ์ด๊ธฐํ
โข
๋ฐ๋ฉ ์ฒ ์ : ์ฌ์ฉ ํ ๋ฐ๋์ Release() ํธ์ถ
โข
์๊ฒฉ ๊ฒ์ฌ ํ์ฑํ(๊ฐ๋ฐ ์ค):
ReferencePool.EnableStrictCheck = true;
C#
๋ณต์ฌ
โข
์ ํฉํ ๋์๋ง ํ๋ง: ์งง๊ฒ ์์ฃผ ์์ฑ๋๋ ๊ฐ์ฒด์ ์ ํฉ(์ค๋ ์ฌ๋/๊ฑฐ์ ์ ๋ง๋๋ ๊ฐ์ฒด๋ X)
โข
ํต๊ณ ๋ชจ๋ํฐ๋ง: GetAllReferencePoolInfos()๋ก ๊ณผ๋ค/๋๋ฝ ํ์ธ
โฆ
๋ฏธ์ฌ์ฉ ์๊ฐ ๋น์ ์์ ์ผ๋ก ํฌ๋ฉด ๊ณผ๋ํ ์ฌ์ ์์ฑ ์์ฌ
โฆ
ํ๋/๋ฐ๋ฉ ๋ถ๊ท ํ์ ๋ฉ๋ชจ๋ฆฌ ๋์ ์ ํธ
๊ฒฐ๋ก (Conclusion)
Reference Pool์ GameFramework์ ํต์ฌ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ์์คํ
์ผ๋ก, ๊ฐ์ฒด ์ฌ์ฌ์ฉ์ ํตํด GC ์ค๋ฒํค๋๋ฅผ ์ค์ด๊ณ ๊ฒ์์ฒ๋ผ ๋ฉ๋ชจ๋ฆฌ์ ๋ฏผ๊ฐํ ํ๊ฒฝ์์ ์์ ์ ์ธ ์ฑ๋ฅ์ ์ ์งํ๊ฒ ๋์์ค๋๋ค.
ํนํ ์ด๋ฒคํธ ์ธ์์ฒ๋ผ ์งง์ ์๋ช
์ฃผ๊ธฐ๋ฅผ ๊ฐ์ง ๊ฐ์ฒด์ ํจ๊ณผ๊ฐ ํฌ๋ฉฐ, ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ๋ฉด GC ์ ์ง ์๊ฐ์ ๋์ ๋๊ฒ ์ค์ฌ ์ ์ฒด ๋ฐ์์ฑ์ ๋์ผ ์ ์์ต๋๋ค.







