c# - Int/Int64 .Net 内存分配

标签 c# .net memory-management garbage-collection heap-memory

我有一个大型应用程序,其内存分配平均约为 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 堆分配的任何建议,以及一些隔离这些分配的技术(调用堆栈会很好,但可能会限制性能)。

最佳答案

I am guessing this is somehow indicating that I am creating a lot of pointers on the heap in some unexpected way?

听起来您更有可能对我装箱了很多 intlong 值。

CallSite 部分听起来像是您经常使用 dynamic(或者在代码中使用非常频繁的部分),这很容易导致更多装箱比静态类型的代码。

我会尝试隔离分配大量对象的代码的特定区域 - 例如,如果您可以仅使用特定的代码路径,那将使您更清楚地了解哪些路径产生的垃圾比你会期待的。看看任何使用 dynamic 的地方,看看你是否真的需要 - 尽管你不应该觉得你必须删除 所有 dynamic 的使用> 通过任何方式;很可能存在一个可以微优化的特定“热点”。

要考虑的另一件事是此分配实际花费了您多少。你说你正试图大幅减少它——你真的需要吗?如果所有这些对象的生命周期都非常短,您可能会发现通过降低分配率并不能显着提高性能。您应该测量在垃圾收集上花费的时间,以确定这可能有多有效。

关于c# - Int/Int64 .Net 内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18681102/

相关文章:

.net - 两个 .NET 项目,一个 DB 连接字符串?

.net - 使用 IDisposable 取消订阅事件

ios - dealloc 是否会调用属性的 setter 来消除它们?

ios - 仪器之间的区别(僵尸和泄漏)

c# - 使用 Entity Framework 和 MySQL 数据库的 WPF MVVM 应用程序无法在未安装 MySqlConnector 的系统上启动

c# - 为什么 MS access odbc 在 C# 中返回数字而不返回字符串?

c# - 利用浏览器缓存不缓存 Javascript 和 CSS 文件

c# - 如何实现时间跨度到字符串的转换?

c# - 如何覆盖 WcF 对象的 ToString 方法?

c++ - 如何在 Linux 上为 C++ 应用程序分配 "huge"页面