我有一个大型应用程序,平均每秒内存分配约为30 MB/秒(根据性能监视器字节分配/秒测量)。我正在努力将其大幅缩减,但分配的来源并不明显。
为了检测问题,我录制了CLR/GC的ETW跟踪,并导出了AllocationTick事件,该事件记录了每次分配了额外的100 KB以及最近分配的对象类型。这产生了一个不错的样本集。三种对象类型占了我分配的70%,但它们还有点神秘。
1. System.Int64 30% 2. System.Int32 28% 3. 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堆分配的任何建议,并且可能有一些隔离这些分配的技术(调用堆栈非常好,但可能会影响性能)。
为了检测问题,我录制了CLR/GC的ETW跟踪,并导出了AllocationTick事件,该事件记录了每次分配了额外的100 KB以及最近分配的对象类型。这产生了一个不错的样本集。三种对象类型占了我分配的70%,但它们还有点神秘。
1. System.Int64 30% 2. System.Int32 28% 3. 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堆分配的任何建议,并且可能有一些隔离这些分配的技术(调用堆栈非常好,但可能会影响性能)。