AOT 컴파일 방식에 대한 질문

.Net MAUI 관련 자료를 보다가 AOT(Ahead Of Time) 컴파일 방식이란걸 알게되었습니다.
MAUI에서 iOS와 WinUI 3 이 이 방식으로 동작한다고 알고있습니다.
AOT 방식으로 컴파일을 하면 실시간 컴파일이 필요없는 최종 기계어 코드를 생성하게 될텐데요.

  1. 프로그램 실행시 CLR 위에서 동작을 하는게 맞나요?
  2. 만약 1번이 맞다면 실시간 컴파일을 안하는 상황에서 가비지콜렉터 같은 런타임 기능들은 어떻게 수행하나요?
좋아요 4

(정확한 내용을 아시는 분의 코멘트, 피드백, 그리고 틀린 부분이 있을 경우 정정해주시면 감사하겠습니다.!)

MAUI (Xamarin)은 내부적으로 Mono를 사용하고 있는 것으로 알고 있고, Mono는 .NET Framework와 마찬가지로 JIT와 AOT로 MSIL을 처리할 수 있습니다.

JIT는 Just-in-Time 컴파일 방식으로, MSIL 코드를 실행하는 시점에서 동적으로 목적 프로세서의 기계어 코드로 변환하는 기법을 말하고, AOT는 Mono나 .NET Framework의 경우 프로그램 실행 전에 별도의 저장소에 MSIL 코드 전체를 목적 프로세서의 기계어 코드로 변환하여 실행용 사본을 별도로 보관하고 사용하는 기법을 말합니다.

서버 환경이 아닌 모바일, 데스크탑 환경에서는 애플리케이션이 적은 전력으로 좀 더 빠른 속도로 실행될 수 있도록 AOT 방식을 채택하는 것 같습니다. 이 때,

  1. Mono의 AOT는 CLR 위에서 여전히 동작하는 것으로 알고 있습니다. 단지 시작 시간을 단축하기 위한 정도로만 AOT를 얕게 수행하는 것으로 알고 있습니다. 그러나 좀 더 공격적으로 AOT를 시도하여 아예 리플렉션, 어셈블리 emitting 같은 동적 요소 일체를 배제하는 NativeAOT나 Unity의 IL Compiler 같은 사례도 있는 것으로 알고 있습니다.

  2. 가비지 컬렉터 같은 기능은 어떤 방법으로 AOT를 진행하든 가비지 컬렉터에 관련된 런타임을 특별히 바이너리에 따로 포함시키게 될 것 같습니다. Rust 같이 언어 수준에서 참조 횟수를 강제하는 등의 장치가 C#이나 .NET 기반 런타임 위에서 실행되는 언어에는 보통 들어있지 않기 때문에 이는 필수 요소일 것 같습니다.

좋아요 6

짧은 답 (정현님의 간단 버젼)

  • JIT으로 동작하더라도 런타임 시 기계어 코드로 변환되고 가비지콜렉터가 동작하므로 AOT가 JIT의 동작을 컴파일 시점에서 미리 수행하고 가비지콜렉터의 동작은 동일하다고 이해하면 쉬운 이해일 것 같습니다.
좋아요 5


MAUI가 모두 AOT 방식으로 바이너리를 만들지는 않고, 플랫폼마다 차이가 있습니다.

  • Android apps built using .NET MAUI compile from C# into intermediate language (IL) which is then just-in-time (JIT) compiled to a native assembly when the app launches.
  • iOS apps built using .NET MAUI are fully ahead-of-time (AOT) compiled from C# into native ARM assembly code.
  • macOS apps built using .NET MAUI use Mac Catalyst, a solution from Apple that brings your iOS app built with UIKit to the desktop, and augments it with additional AppKit and platform APIs as required.
  • Windows apps built using .NET MAUI use Windows UI 3 (WinUI 3) library to create native apps that target the Windows desktop. For more information about WinUI 3, see Windows UI Library.

참고: What is .NET MAUI? - .NET MAUI | Microsoft Docs

  1. 프로그램 실행시 CLR 위에서 동작을 하는게 맞나요?

CLR은 맞습니다만, 흔히 아는 Managed 런타임과는 다른 MRT(Minimal CLR Runtime)를 사용합니다.




참고: CoreRT - A .NET Runtime for AOT · Performance is a Feature!

  1. 만약 1번이 맞다면 실시간 컴파일을 안하는 상황에서 가비지콜렉터 같은 런타임 기능들은 어떻게 수행하나요?

CLR 위에서 동작하므로 가비지 컬렉팅 기능이 포함될 것으로 보입니다만, 정확한 자료는 보이지는 않습니다.
다만, 아래의 시나리오는 동작하지 않을 수 있습니다.

  • 리플렉션
  • 동적 또는 런타임 바인딩 호출.
  • serialization 및 deserialization
  • COM interop

ORM의 serilziation/deserialization 그리고 mvvm 패턴 사용시 viewmodel 내부에서 많이 쓰이는 리플렉션 기능을 사용하는데 한계가 있기 때문에 이를 해결하기 위한 방법들이 있습니다.
CoreRT - A .NET Runtime for AOT · Performance is a Feature! 에 히스토리가 나와 있습니다.
참고: .NET 네이티브 및 컴파일 - UWP applications | Microsoft Docs

근데 .net7에 진행중인 nativeaot가 ga 되면 양상이 달라지겠네요 :sweat_smile:

좋아요 8