Es werden nicht alle Assemblies vorkompiliert wenn du .NET Anwendungen laufen lässt, sondern nur dann wenn das Framework selbst installiert wird.
Die einzelnen Assembies (die von .NET Programmen genutzt werden) werden nach der Installation passend zu deinem System kompiliert, damit nicht immer der JIT-Compiler (JIT = just in time) ran muss.
Auch das NBFC Setup kompiliert bei der Installation alle NBFC Assemblies per
ngen.exe und legt sie im Native Image Cache ab.
Ein Aufruf eines .NET Programms sieht vereinfacht gesagt so aus:
- Benutzer führt Datei aus
- der Loader des OS erkennt dass es ne .NET Anwendung ist und startet die CLR
- die CLR schaut im Native Image Cache für jede Assembly ob ein vorkompiliertes Image vorhanden ist
- falls ja wird das Image in den Speicher geladen, falls nein wird der JIT-Compiler gestartet der dann den auszuführenden Code kompiliert
- Code der nun in Binärform im Speicher liegt wird ausgeführt
Btw. es ist aber tatsächlich so, dass .NET Anwendungen, sofern keine nativen Images im Cache liegen, immer während der Ausführung (just in time) kompiliert werden. (allerdings nicht der komplette Code auf einen Schlag, sondern immer nur das was gerade benötigt wird).
Vorteile:
- Plattformunabhängige Assemblies (es muss nur ne CLR Implementierung für die jeweilige Plattform vorhanden sein, vergleichbar mit Java bzw. der Java Runtime)
- Optimierungen während der Laufzeit durch die CLR bzw. den JIT-Compiler sind möglich
Nachteile:
- overhead durch den JIT-Compiler und die CLR