NativeAOT 会显著降低启动时间和内存占用,但可能削弱高并发下的吞吐能力
NativeAOT 编译后,
dotnet publish输出的是纯本地二进制,没有 JIT 编译开销和运行时元数据,因此冷启动接近零——这对 serverless 或短生命周期服务很关键。但代价是:所有泛型实例在编译期全量展开,类型爆炸会导致最终二进制体积膨胀,且无法使用运行时动态代码生成(如
Reflection.Emit、
Expression.Compile),很多高性能网络库(如早期版本的
Kestrel)依赖这些机制做连接复用或 pipeline 优化。
高并发场景下更敏感的是线程调度和 GC 行为:
NativeAOT默认启用
ServerGC,但无法动态调优(如
GC.Collect调用被禁用,
GCSettings.LatencyMode无效),且堆外内存(如
MemoryMappedFile、
Unsafe.Allocate)需手动管理,稍有不慎就引发泄漏或竞争。
低延迟应用必须关闭 GC 并严格控制堆分配
NativeAOT 不等于“无 GC”——它仍保留一个精简版
SGC(Simple GC),仅支持
Gen0回收,且不可禁用。真正实现亚毫秒级延迟,必须做到: 所有高频路径(如网络包解析、序列化)使用
Span<byte></byte>和
stackalloc,避免
new byte[]或
string构造 禁用
System.Text.Json的默认反射序列化,改用源生成器(
JsonSerializerContext+
[JsonSourceGenerationOptions]) 避免
async/await在 hot path 上创建状态机对象;必要时用同步 I/O + IOCP 模式(如
Socket.ReceiveAsync配合
MemoryPool<byte></byte>) 通过
rd.xml显式保留必需的反射目标,否则
typeof(T).GetMethod在运行时返回
null
并发模型受限,ThreadPool
行为与传统 .NET 不同
NativeAOT 下
ThreadPool仍可用,但初始线程数固定(默认 1),且
ThreadPool.SetMinThreads无效。这意味着: 大量短时任务(如每请求一个
Task.Run)会排队等待,而非快速扩容
Parallel.For等并行构造可能退化为串行执行 推荐改用固定大小的
Channel<t></t>+ 预启动 worker loop(
while (!ct.IsCancellationRequested)),完全绕过线程池
另外,
Task对象本身在 NativeAOT 中开销更大(无 JIT 优化,所有 awaiter 都是虚方法调用),高频创建
Task.CompletedTask也会累积压力。
调试和可观测性能力大幅下降,问题定位成本上升
没有 JIT,意味着没有
dotnet-dump的托管堆快照、没有
dotnet-trace的 GC/ThreadPool 事件、也没有
PerfView的 IL 级别采样。你能拿到的只有:
perf record -e cycles,instructions,page-faults(Linux)或
ETW(Windows)的原生事件 通过
Microsoft.Diagnostics.Runtime(当启用
EmbedInteropTypes=true且导出符号)读取有限堆信息 日志必须提前注入
ActivitySource+
EventSource,且不能依赖
DiagnosticSource的订阅机制(部分被裁剪)
一个典型陷阱:
Console.WriteLine在 NativeAOT 中底层调用
write()系统调用,高并发写 stdout 会成为瓶颈,应替换为无锁 ring buffer + 单独 flush 线程。
using System.Buffers;
using System.IO.Pipelines;
// 推荐的日志缓冲模式(非阻塞)
var pipe = new Pipe(new PipeOptions(
pool: MemoryPool<byte>.Shared,
minimumSegmentSize: 4096));
// 后续通过 pipe.Writer 以 Span 形式写入,避免 string → UTF8 编码分配
NativeAOT 不是“一键低延迟”,而是用编译期确定性换掉运行时灵活性。真正压测时,常发现瓶颈不在 CPU 或网络,而在某个被忽略的
ToString()调用触发了隐式
StringBuilder分配——这种细节,在传统 .NET 里可以靠 GC 日志快速定位,而在 NativeAOT 里得靠
perf script反查 callgraph。
