일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 암호화
- AES
- 커스텀 패키지
- jumping ball
- C#
- 가이드
- 2D Camera
- 이미지 폰트
- 최적화
- Job 시스템
- 샘플
- Framework
- job
- Dynamic Font
- base64
- Dots
- 단말기 해상도
- RSA
- Custom Package
- unity
- 다이나믹 폰트
- sha
- Unity Editor
- TextMeshPro
- 프레임워크
- 텍스트 메시 프로
- adfit
- Tween
- ui
- DotsTween
Archives
- 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의 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
https://docs.microsoft.com/ko-kr/dotnet/api/system.reflection.emit.opcodes.constrained?view=net-6.0
'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 최적화 (0) | 2020.05.20 |