Unity ๋ Memory ์ฑ๋ฅ์ ์ํด 3๊ฐ์ง Memory ๋ฅผ ์ฌ์ฉํ๋ค.
1. Managed memory: Heap ๊ณผ Garbage Collector ๋ก ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์๋์ผ๋ก ํ ๋น&ํด์ ํ๋ ๋ฉ๋ชจ๋ฆฌ
2. C# unmanaged memory: C# Collections package ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ก ๊ตฌํ ๋ฐ ๊ด๋ฆฌ ๊ฐ๋ฅ.
3. Native memory: Unity Engine ์ ์คํํ๋๋ฐ ์ฌ์ฉํ๋ C++ ๋ฉ๋ชจ๋ฆฌ. ์ฌ์ฉ์๊ฐ ์ง์ Access ํ ์๋ ์์ผ๋ ์๊ณ ๋ ์์ด์ผ ํ๋ ๋ถ๋ถ.
* Managed memory
Mono ์ IL2CPP ์ scripting virtual machines(VMs)์ Managed memory ๋ฅผ ์คํํ๋ค.
1) The managed heap: VMs ๊ฐ Garbage Collector ๋ก ์๋์ผ๋ก ์ปจํธ๋กคํ๋ ๋ฉ๋ชจ๋ฆฌ ๋ถ๋ถ.
๊ทธ๋์ managed heap ์ ํ ๋น๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ GC Allocation ์ด๋ผ๊ณ ๋ถ๋ฆ ๋๋ค. GC Allocation ์ Profiler ๊ฐ ๊ธฐ๋กํ๋ค.
ํ์ ์ ์ ๊ณผ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ ๋จํธํ๊ฐ ๋ฐ์ํ์ ๋, GC ๋ 1) ๋น๊ณต๊ฐ์ ๋จผ์ ๋ฃ๊ธฐ๋ฅผ ์๋ํ๊ณ , ์๋ ๊ฒฝ์ฐ 2) ํ์ ํ์ฅํฉ๋๋ค.
* ์ด ๋, ํ์ ์ด์ ๋ฉ๋ชจ๋ฆฌ์ 2๋ฐฐ ๋งํผ ํ์ฅ ๋ฉ๋๋ค. <- ์ด๊ฒ ๋ฌธ์
ex) reference ํ์
, boxing ๋ ๊ฐํ์ object.
Built-in reference types - C# reference - C#
Learn about reference types that have C# keywords you can use to declare them.
learn.microsoft.com
Boxing and Unboxing - C# Programming Guide - C#
Learn about boxing and unboxing in C# programming. See code examples and view additional available resources.
learn.microsoft.com
2) The scripting stack: ์ฝ๋ ๋ฒ์ { } ์์์ ํ ๋น๋๊ณ ํด์ ๋๋ ๋ถ๋ถ.
3) Native VM memory: Unity Scripting Layer ์ ๊ด๋ จ๋ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํฌํจ๋๋ค. Generics ์ฌ์ฉ๊ณผ ๊ด๋ จ๋ ๋ฉ๋ชจ๋ฆฌ, reflection์ด ์ฌ์ฉํ๋ ๋ฉํ ๋ฐ์ดํฐ, VMs ์ ์คํํ๋๋ฐ ํ์ํ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํฌํจ๋์ด ์๋ค๋ ๊ฑด ์๊ณ ์์.
- Managed memory์ ์ฅ์ : ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์๋์ผ๋ก ํด์ค.
- Managed memory์ ๋จ์ : ๋ฉ๋ชจ๋ฆฌ ํด์ /ํ ๋น ๋ฐฉ์์ ์์ธกํ ์ ์์ด์ ๋ถ์์ ํ ์ฑ๋ฅ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค. ์์ธก ๊ฐ๋ฅํด์ผ๋ง ํ๋ ๋ถ๋ถ์ C# unmanaged memory ๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
* C# unmanaged memory
job system, burst ๋ฑ ๋ฉ๋ชจ๋ฆฌ ์์ธก์ด ๊ฐ๋ฅํด์ผํ ๊ฒฝ์ฐ C# Collection package ๋ฐ์ดํฐ ๊ตฌ์กฐ์ Allocator๋ฅผ ๋ก C# unmanaged memory ๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
NativeArray<int> nums = new NativeArray<int>(10, Allocator.TempJob);
// Create and schedule a job that uses the array.
ExampleJob job = new ExampleJob { Nums = nums };
JobHandle handle = job.Schedule();
// Create and schedule a job that will dispose the array after the ExampleJob has run.
// Returns the handle of the new job.
handle = nums.Dispose(handle);
Collections package | Collections | 2.4.0
Collections package The Collections package provides unmanaged data structures that you can use in jobs and Burst-compiled code. Additional resources
docs.unity3d.com
* Native memory
Unity ์์ง ๋ด๋ถ์ C/C++ ์ฝ์ด์ ์๋ Native Memory. Unity ์์ฒด ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ์์คํ ์ด๋ค. ์ง์ ์ ๊ทผ์ ๋ถ๊ฐ๋ฅํ๋ Profiler Marker ๋ก ์ด ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๋ค ์ํฅ์ ๋ฏธ์น๋์ง ํ์ธํ ์ ์๋ค.
Unity - Manual: Common Profiler markers
Profiling your application Common Profiler markers Unity’s code is instrumented with a large number of ProfilerA window that helps you to optimize your game. It shows how much time is spent in the various areas of your game. For example, it can report th
docs.unity3d.com
The managed heap ์์ ๋์๋ Garbage Collector ๊ฐ๋ ์ ์์ธํ ์ดํด๋ณด์.
*Garbage Collector: Unity ๊ฐ ๋์ด์ ์ฌ์ฉํ์ง ์๋ ๊ฐ์ฒด์์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ ํจ.
Heap ์ ํ ๋น์ ์๋ํ๋๋ฐ Heap์ ํ ๋น์ ์์ํ ์ฌ์ ๊ฐ ์์ ๊ฒฝ์ฐ Garbage Collector ๋ฅผ ์คํ ํจ.
Garbage Collector ๊ฐ ๋ ์ด์ ์ฐธ์กฐํ์ง ์๋ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ์ญ์ ํ์ฌ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ๋ณดํจ.
- Garbage Collector ์์ฑ 2๊ฐ์ง
1) Incremental garbage collector: Garbage Collector ํ๋ก์ธ์ค๋ฅผ ํ๋ฒ์ ์คํํ๋๊ฒ์ด ์๋๋ผ ์ฌ๋ฌ ํ๋ ์์ ๊ฑธ์ณ ์คํํ๋ค.
2) Incremental garbage collector disabled: Incremental GC ๋ฅผ ๋นํ์ฑํํ๋ฉด GC๊ฐ Heap ์ ๊ฐ์ฒด๋ฅผ ๊ฒ์ฌํ๊ณ ์ฒ๋ฆฌํ๊ธฐ ์ํด Application ์คํ์ ์ค์งํด๋ฒ๋ฆฐ๋ค.
=> GC ๋ฅผ ์ชผ๊ฐ์ ์คํํ๋ ๊ฒ์ด ๋์ ๊ณณ๊ณผ GC ๋ฅผ ํ๋ฒ์ ์คํํ๋ ๊ฒ์ด ๋์ ๋ถ๋ถ์ด ์๊ธฐ์ Incremental GC ๋ฅผ ์คํ์์ผ์ ํ๋ ์์ ๋จ์ดํธ๋ฆด ๊ฑด์ง ํ๋ ์์ด ์ด์ง ๋ฉ์ถ๋๋ผ๋ ํ๋ฒ์ ์ ๋ฆฌํ๋๊ฒ ๋์ ๊ฒ์ธ์ง ๊ณ ๋ฏผ์ด ํ์ํ๋ค.
3) Disable automatic garbage collector: ์๋ GC ์ฌ์ฉ ์ํจ. ์๋์ ๊ฐ์ ์ฝ๋๋ก GC ๋ฅผ ์คํํ๋ ์๊ธฐ๋ฅผ ์์ ํ ์ ์ดํ ์ ์๋ค.
// GC ํ์ฑํ
GarbageCollector.GCMode = GarbageCollector.Mode.Enabled;
// GC ๋นํ์ฑํ
GarbageCollector.GCMode = GarbageCollector.Mode.Disabled;
// ์ ์ง์ GC ์ฃผ๊ธฐ ์ค์
GarbageCollector.CollectIncremental(ulong nanoseconds);
* GC ์ Allocation ์ ์ถ์ ํ ์ ์๋ ๋ฐฉ๋ฒ
: Unity Profiler ์ CPU Usage module, Unity Profiler ์ Memory Module, The Memory Profiler package:
* GC ํธ๋ฆฌ๊ฑฐ๋ฅผ ์ค์ด๋ ๋ฐฉ๋ฒ
1) Managed Heap ์ฌ์ฉ๋์ ์ค์ด์.
2) ์ฌ์ฌ์ฉ๊ฐ๋ฅํ Object Pool ์ ์ฌ์ฉํ์
3) ๋ฌธ์์ด์ ์ฐ๊ฒฐํ ๋ System.Text.StringBuilder ๋ฅผ ์ฌ์ฉํ์.
: C# ์ ๋ฌธ์์ด์ ๋ถ๋ณ์ฐธ์กฐ ์ ํ์ด๋ค. ๋ฐ๋ผ์ ๋ฌธ์์ด ๋ณ์๊ฐ ์ผ๋จ ์์ฑ๋๋ฉด ์์ ํ ๋ ์์ ํ ์๋ก์ด ๋ฌธ์์ด์ด ์์ฑ๋์ด Heap ์ ์ ์ฅ๋๋ค. ๋ฐ๋ผ์ ๋ฌธ์์ด์ ์ฐ๊ฒฐํด์ผ ํ๋ค๋ฉด System.Text.StringBuilder ์ฌ์ฉํ์.
using UnityEngine;
public class ExampleScript : MonoBehaviour {
string ConcatExample(string[] stringArray) {
string result = "";
for (int i = 0; i < stringArray.Length; i++) {
result += stringArray[i];
}
return result;
}
}
"A", "AB", "ABC", "ABCD", "ABCDE" ๊ฐ heap ์ ์ ์ฅ๋๋ค. "ABCDE" ๋ง ์์ผ๋ฉด ๋๋๋ฐ ๋๋จธ์ง ๊ฒ๋ค์ด ์ค๋ณต ํ ๋น ๋๋ ๊ฒ.
// Good C# script example: StringBuilder avoids creating temporary strings,
// and only allocates heap memory for the final result string.
using UnityEngine;
using System.Text;
public class ExampleScript : MonoBehaviour {
private StringBuilder _sb = new StringBuilder(16);
string ConcatExample(string[] stringArray) {
_sb.Clear();
for (int i = 0; i < stringArray.Length; i++) {
_sb.Append(stringArray[i]);
}
return _sb.ToString();
}
}
4) ๋ฐฐ์ด ๊ฐ์ ๋ฐํํ๋ ๋ฉ์๋๋ ๋ฐฐ์ด์ด reference type ์ด๋ผ๋ ๊ฒ์ ์ด์ฉํ์.
using UnityEngine;
using System.Collections;
public class ExampleScript : MonoBehaviour {
float[] RandomList(int numElements) {
var result = new float[numElements];
for (int i = 0; i < numElements; i++) {
result[i] = Random.value;
}
return result;
}
}
RandomList ํจ์๋ฅผ ํธ์ถํ ๋ ๋ง๋ค ๋ฐฐ์ด์ด ์์ฑ๋์ด heap ์ ํ ๋น๋๊ณ result ๋ฅผ ๋ฐํํ ํ์๋ result ๊ฐ์ด heap ์ ๋จ์ ์๋๋ค.
using UnityEngine;
using System.Collections;
public class ExampleScript : MonoBehaviour {
void RandomList(float[] arrayToFill) {
for (int i = 0; i < arrayToFill.Length; i++) {
arrayToFill[i] = Random.value;
}
}
}
์์ ๊ฐ์ด ์ธ์๋ก ๋ณด๋ด๋ฉด reference type ์ด๋ฏ๋ก ๋ฐฐ์ด์ ์ฌ์ฌ์ฉํ์ฌ heap ์ ์๋กญ๊ฒ ํ ๋น๋์ง ์๋๋ค.
5) Collection ๊ณผ Array ๋ฅผ ์ฌ์ฌ์ฉํ์.
void Update() {
List<float> nearestNeighbors = new List<float>();
findDistancesToNearestNeighbors(nearestNeighbors);
nearestNeighbors.Sort();
// … use the sorted list somehow …
}
์ ์ฝ๋๋ Update ๋ฌธ์ด ํธ์ถ๋ ๋ ๋ง๋ค List ๋ฅผ ๊ณ์ ์์ฑํ์ฌ Heap ์ ํ ๋นํ๋ค.
List<float> m_NearestNeighbors = new List<float>();
void Update() {
m_NearestNeighbors.Clear();
findDistancesToNearestNeighbors(NearestNeighbors);
m_NearestNeighbors.Sort();
// … use the sorted list somehow …
}
ํ๋ฒ ์์ฑํ List ๋ฅผ ์ฌ์ฌ์ฉํ์ฌ ์ฌ์ฉํ๋ฉด Heap ์ ์๋ก ํ ๋นํ์ง ์๋๋ค.
6) Boxing ์ ํผํ์.
: Boxing ์ ์์ ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ ์ผ๋ฐ์ ์ธ ์์ธ ์ค์ ํ๋๋ค. Value ์ ํ์ ๋ณ์๊ฐ Reference ์ ํ์ผ๋ก ๋ณํ๋ ๋ ๋ฐ์ํ๋ค.
int x = 1;
object y = new object();
y.Equals(x);
7) Array-valued Unity APIs๋ฅผ ์ฌ์ฉํ ๋ single array allocation ์ ์ด์ฉํ์.
void Update() {
for(int i = 0; i < mesh.vertices.Length; i++) {
float x, y, z;
x = mesh.vertices[i].x;
y = mesh.vertices[i].y;
z = mesh.vertices[i].z;
// ...
DoSomething(x, y, z);
}
}
Loop ์์ mesh.vertices.Length๋ฅผ ํธ์ถํ๊ฒ ๋๋ฉด Loop ๊ฐ 1ํ ๋์ํ ๋๋ง๋ค 4๊ฐ์ ์ ์ ๋ฐฐ์ด ๋ณต์ฌ๋ณธ์ ๋ถํ์ํ๊ฒ ๋ง๋ ๋ค. ํ ๋น์ .vertices ์์ฑ์ ์ ๊ทผํ ๋๋ง๋ค ์ด๋ฃจ์ด์ง๋ค.
void Update() {
var vertices = mesh.vertices;
for(int i = 0; i < vertices.Length; i++) {
float x, y, z;
x = vertices[i].x;
y = vertices[i].y;
z = vertices[i].z;
// ...
DoSomething(x, y, z);
}
}
Loop ๊ตฌ๋ฌธ ์ ์ vertices ๋ฅผ ์ ์ฅํ์ฌ single array ํ ๋น์ผ๋ก ๋ง๋ค ์ ์๋ค.
List<Vector3> m_vertices = new List<Vector3>();
void Update() {
mesh.GetVertices(m_vertices);
for(int i = 0; i < m_vertices.Length; i++) {
float x, y, z;
x = m_vertices[i].x;
y = m_vertices[i].y;
z = m_vertices[i].z;
// ...
DoSomething(x, y, z);
}
}
๊ฐ์ฅ ๋ฒ ์คํธ๋ ์์ ์ฝ๋ ์ด๋ค. Update ๊ตฌ๋ฌธ ๋ฐ์์ vertice ๋ค์ ๊ฐ๊ณ ์๋ ๊ฒ.
๊ทธ ์ธ ํ ๋น๋๋ API์ ํ ๋น๋์ง ์๋ API ๋ ์๋์ ๊ฐ๋ค. ๊ฐ๋ฅํ๋ฉด Non-allocating API ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ ๋ฐฉ๋ฒ์ด๋ค.
'๐ฎ Unity Study > Unity' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Unity Document Study] 2์ฃผ์ฐจ :: Asset Workflow (0) | 2024.05.11 |
---|---|
[Unity Document Study] 1์ฃผ์ฐจ :: Unity Analysis - Unity Profiler (0) | 2024.05.02 |
[Unity] Prefab Variant ํ๋ฆฌํน ์์ (0) | 2024.04.30 |
[Unity] Sound ๋ชจ๋ฐ์ผ ์ต์ ํ (0) | 2024.04.30 |
Unity Canvas :: Reference Pixels Per Unit (0) | 2024.04.16 |