我有一个大型应用程序,其内存分配平均约为 30 mb/秒(每个性能监视器分配的字节数/秒测量)。我正试图大幅减少这一点,而分配的来源并不明显。
为了检测事物,我记录了 CLR / GC 的 ETW 跟踪,并导出了 AllocationTick 事件,该事件记录每次额外分配 100 KB 时,以及最近分配的对象类型是什么。这会产生一个大小合适的样本集。三种对象类型占我分配的 70%,但它们有点神秘。
- System.Int64 30%
- System.Int32 28%
- System.Runtime.CompilerServices.CallSite'1[System.Func'3[System.Runtime.CompilerServices.CallSite,System.Object,System.Object]] 12%
数据集大约 70 分钟和一百万个事件,所以我对这些数字很有信心。
我猜这在某种程度上表明我以某种意想不到的方式在堆上创建了很多指针?(这是一个 x64 应用程序)
我使用了一些 linq 和 foreach 循环,但这些应该只在堆栈上创建增量变量,而不是在堆上。
我也在 TPL / Dataflow 库之上运行所有东西,这可能会生成这些。
我正在寻找有关可能导致这么多 int32/64 堆分配的任何建议,也许还有一些隔离这些分配的技术(调用堆栈会很棒,但性能可能会令人望而却步)。