게임엔진/Unity

List를 사용할 때 Reserve해야하는 이유

CodeJB 2023. 7. 3. 17:08

List는 Size가 가변적인 Collection이다. List에 데이터를 Add할 때 내부코드는 아래와 같다.

=> Add 를 호출하면 현재 배열의 사이즈를 비교하고 if (this._size == this._items.Length) 가득찼다고 판단하면 EnsureCapacity 메서드를 호출한다.

=> EnsureCapacity를 보니, Length가 0이 아니면 무조건 Length의 2배를 Capacity Property에 할당해버림


  => 일단 new T[value]로 destinationArray라는 새로운 배열 객체를 생성하는데, EnsureCapacity로부터 받은 원래 사이즈의 두배 만큼의 메모리공간을 할당함.
=> 그 다음 destinationArray에 원래 데이터들을 Copy한다음의 기존에 _items 배열에 재할당함. 반복적인 재할당으로 인해 메모리 파편화 문제도 발생할듯.

=> 결과적으로 재할당이 반복되면서 가비지가 계속해서 쌓이는 구조가댐.
=> 추가해야할 데이터가 10000개라면 4 + 8 + 16 + 32 + 64 + 128 + 256 + 512 + 1024 + 2048 + 4096 + 8192 + 16384 = 32764개의 메모리 영역이 필요함. 그리고, 레퍼런스 카운트가 0이된 4부터 8192까지 더한 16380개의 메모리는 쓰레기가 댐.


따라서,
=> 리스트 생성자를 통해 미리 사용할 만큼의 크기를 지정함으로써, 가비지 최소화와 메모리 파편화를 최소화할 수 있게 됨.
=> 결론 : 리스트의 크기를 예측할 수 있다면 미리 Reserve해놓자.

'게임엔진 > Unity' 카테고리의 다른 글

클래스와 구조체 차이  (0) 2023.07.03
제네릭 한정자 in,out 공변성과 반공변성  (0) 2023.07.03
제네릭 타입 추론  (0) 2023.07.03
MONO / IL2CPP / AOT/ JIT  (0) 2022.05.22