

新闻资讯
行业动态struct在高并发下更快因其值类型特性,分配于栈或内联,免GC;class为引用类型,堆分配加剧GC压力与锁竞争。但过大struct或频繁值传递、逃逸至堆时反而更慢。
因为 struct 是值类型,分配在栈上(或内联在容器中),不经过 GC;而 class 是引用类型,每次 new 都触发堆分配,高并发时会快速产生大量短生命周期对象,加剧 GC 压力——尤其是 Gen0 频繁回收,直接拖慢吞吐量。
new MyClass() → 多个堆内存请求 → 竞争 GC heap lock(.NET 6+ 改进但仍有开销)MyStruct → 栈指针偏移即可,无同步、无跟踪、无 finalizer 开销当结构体过大(通常 >16 字节)或频繁按值传递时,复制成本会反超引用传递。高并发场景下尤其明显:比如一个 64 字节的 struct 被当作方法参数传入 10 万次/秒,CPU 缓存带宽和寄存器压力会显著上升。
MyLargeStruct s(而非 ref MyLargeStruct s)→ 每次调用复制全部字段List → 扩容时整块内存 memcpy,比 List 的指针数组复制重得多以高频消息处理(如 WebSocket 心跳包解析、订单快照生成)为例,优先用 struct,但必须满足「小、不可变、无引用字段」三原则:
public readonly struct OrderSnapshot
{
public readonly long OrderId;
public readonly decimal Price;
public readonly int Status;
public readonly DateTime Timestamp;
public OrderSnapshot(long id, decimal price, int status, DateTime ts)
{
OrderId = id;
Price = price;
Status = status;
Timestamp = ts;
}
}
readonly,避免意外修改引发线程安全问题string、List、object 等引用类型字段(否则仍需 GC 管理)Span + BinaryPrimitives 直接写入,避开 JsonSerializer.Serialize 的反射开销很多人以为 struct 天然线程安全,其实不然。多个线程操作同一个可变 struct 实例(比如共享在 static 字段或 ConcurrentQueue 中)会导致读写撕裂——因为 struct 复制是逐字段进行的,非原子。
public static MyMutableStruct SharedData; → 线程 A 写 SharedData.X,线程 B 同时读整个 SharedData,可能拿到 X 新值 + Y 旧值lock,若锁粒度覆盖不到所有字段访问路径,仍可能出错readonly struct),要么改用 class + 显式同步,或者用 Interlocked 操作单个字段