Part 2 · 1 chapters · ~8 min
The CLR
Roslyn and IL, assemblies and metadata, the tiered JIT and dynamic PGO, ReadyToRun and Native AOT, the generational garbage collector, workstation versus server GC, the Large Object Heap, finalisers and IDisposable, reflection and source generators, and the history from .NET Framework to cross-platform .NET.
3
Managed code, compiled twice
code
dotnet build -c Release # C# → IL in bin/Release/net10.0/*.dll
dotnet publish -c Release -r osx-arm64 -p:PublishAot=true # Native AOT: a single native binary
// deterministic cleanup: IDisposable and using
await using var conn = await dataSource.OpenConnectionAsync(); // disposed at end of scope
// source generators replace runtime reflection (faster, AOT-friendly)
[JsonSerializable(typeof(TransferDto))] partial class AppJsonContext : JsonSerializerContext { }
DOTNET_gcServer=1 ./ledger # server GC: a heap per core, higher throughput
dotnet-counters monitor -p <pid> System.Runtime # gc-heap-size, gen-0-gc-count, threadpool-queue-lengthHistory: .NET Framework (2002) was Windows-only; .NET Core (2016) was a cross-platform, open-source rewrite; since .NET 5 (2020) there is one ".NET" that runs on Linux, macOS and Windows, with a new major version every November and long-term support for even-numbered releases.
THE CLR: FROM C# TO MACHINE CODE
compile to IL, JIT in tiers, collect garbage by generation
swipe the figure sideways, or tap expand for full screen
1/4
IL
The Roslyn compiler turns C# into Intermediate Language plus metadata in assemblies; any .NET language (C#, F#, VB) targets the same IL.
C# → ILlanguage-neutral