일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- 암호화
- DotsTween
- 패스트캠퍼스후기
- Unity Editor
- ui
- 패스트캠퍼스
- job
- 환급챌린지
- 직장인공부
- 오공완
- 커스텀 패키지
- Framework
- unity
- adfit
- AES
- 2D Camera
- 직장인자기계발
- TextMeshPro
- Tween
- 가이드
- base64
- Job 시스템
- Dots
- C#
- Custom Package
- 최적화
- RSA
- sha
- 샘플
- 프레임워크
- Today
- Total
EveryDay.DevUp
[Unity] Foreach의 GC의 원인 및 수정 본문
Unity 5.5 미만 버전에서 foreach를 사용할 경우 가비지가 발생하는 이슈가 있었다.
원인
- Mono C# Unity 버전에서 foreach loop 종료 시 값을 강제로 박싱
- 값 형식의 열거자를 생성하였는데, 해당 열거자를 사용할 경우 loop가 종료되는 시점에 IDisposable 인터페이스를 구현 해야 했음
- 인터페이스는 참조 형식이기 때문에, 값 형식을 인터페이스로 변환하는 중에 박싱이 발생하게 됨
참고 : https://everyday-devup.tistory.com/106
[Unity] Struct (구조체)
Struct (구조체)? - 데이터와 관련 기능을 캡슐화할 수 있는 값 형식 캡슐화 : 데이터와 기능을 하나로 묶고, 구현 내용 일부를 외부에 감춤 특징 1. 매개 변수가 없는 생성자를 선언할 수 없음 ( 단,
everyday-devup.tistory.com
대응
- Unity의 C# 컴파일러가 최신 버전의 Mono 컴파일러로 업그레이드 되면서 수정 됨
List<int> intList = new List<int>{ 1, 2, 3 };
foreach( int i in intList) {}
// foreach IL GetEnumerator
[__DynamicallyInvokable]
public List<T>.Enumerator GetEnumerator() => new List<T>.Enumerator(this);
// valueType의 eumerator는 IDisposable interface를 구현
public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
public interface IDisposable
{
[__DynamicallyInvokable]
void Dispose();
}
// Unity 버전 5.5 미만에서는
finally
{
IL_0030: ldloc.2 // V_2
// valueType에서 interface (참조형식) 박싱을 해서 Dispose를 호출
IL_0031: box valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<int32>
IL_0036: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_003b: endfinally
}
// Unity 버전 5.5 이상에서는
finally
{
IL_0035: ldloca.s V_0
// 박싱이 발생하지 않음, ValueType List<T>.Enumerator의 포인터를 직접 넘겨주게 변경 됨.
// C# constrained접두사는 callvirt this Type 이 값 형식 인지 또는 참조 형식 인지에
// 관계 없이 일관 된 방식으로 명령을 수행할 수 있도록 설계 되었습니다.
IL_0037: constrained. valuetype [netstandard]System.Collections.Generic.List`1/Enumerator<int32>
IL_003d: callvirt instance void [netstandard]System.IDisposable::Dispose()
IL_0042: endfinally
}
* 출처 및 참고 블로그
https://docs.unity3d.com/kr/2019.4/Manual/BestPracticeUnderstandingPerformanceInUnity4-1.html
관리되는 힙에 대한 이해 - Unity 매뉴얼
많은 Unity 개발자들이 겪는 또 다른 일반적인 문제는 예기치 않은 관리되는 힙(managed heap)의 확장입니다. Unity에서 관리되는 힙은 축소되는 것보다 더 쉽게 확장됩니다. 이와 더불어, Unity의 가비
docs.unity3d.com
(중급) 유니티의 Foreach는 여전히 악의 근원일까요?
대한민국 모임의 시작, 네이버 카페
cafe.naver.com
https://docs.microsoft.com/ko-kr/dotnet/api/system.reflection.emit.opcodes.constrained?view=net-6.0
OpCodes.Constrained 필드 (System.Reflection.Emit)
가상 메서드가 호출되는 형식을 제한합니다.Constrains the type on which a virtual method call is made.
docs.microsoft.com
'Unity > 최적화' 카테고리의 다른 글
[Unity] AssetPostprocessor (어셋 포스트 프로세서) - 어셋을 코드로 관리하기 (0) | 2020.06.11 |
---|---|
[Unity] Sprite Atlas ( 스프라이트 아틀라스 ) (0) | 2020.05.29 |
[Unity] 9-Slice ( 나인 슬라이스 ) 이미지 (0) | 2020.05.27 |
[Unity] Draw Call ( 드로우콜 ), Batching ( 배칭 ) (0) | 2020.05.25 |
[Unity] UGUI 최적화 (2) | 2020.05.20 |