为什么C#中foreach会分配int数组?Rider DPA该提示的原因是什么?
问题一:C#中foreach语句产生int数组分配的原因
首先明确,直接遍历强类型int[]数组的foreach语句不会产生额外的数组分配,只有以下特殊场景才会出现该行为:
- 遍历的目标是
IEnumerable<int>/IList<int>等接口类型的int序列,而非原生强类型数组:如果该序列由LINQ操作(Where/Select/Skip等)、自定义迭代器生成,部分实现内部会创建int数组做元素缓冲,遍历过程就会触发数组分配 - 遍历的是自定义/第三方集合类型:该集合的
GetEnumerator()方法实现内部隐含创建了int数组用于存储枚举上下文或者元素副本 - 遍历场景存在语法糖隐式转换:比如遍历
Enumerable.Range生成的整数序列、在闭包/异步方法中遍历值类型集合,编译器生成的状态机可能会创建int数组捕获集合内容
问题二:Rider DPA给出分配提示的依据
Rider DPA(动态程序分析)是基于运行时采样的性能分析工具,给出该提示的判定逻辑如下:
- 运行时实际捕获到了对应foreach代码行的托管堆int数组分配调用栈,确认分配行为确实和这段代码的执行直接相关
- 该分配的频次、占用内存大小达到了工具内置(或用户自定义)的告警阈值,属于不必要的可优化隐式分配范畴
- 你可以点击提示查看详细分配堆栈,进一步定位数组分配的具体来源
相关提示截图:
内容的提问来源于stack exchange,提问作者Sergey Slepov
相关产品推荐
相关产品推荐

