Joh*_*est 6 .net garbage-collection azure
我们的Web应用程序有数百个用户,并且(一如既往)主要由旧代码组成。
迁移到Azure后,我们可以查看和衡量比以前更多的指标。我们遇到了性能问题,我发现我们的垃圾回收正在不断进行(如“性能计数器”部分下的Web应用程序的“诊断”标签中所测量)。一分钟内,我们就能得到以下数字:
这仅用于18580个HTTP请求,因此平均而言,我们有:
即使请求数量保持不变,这些数字仍在增加(请参见图表)
我的问题/评论是:
约翰,非常感谢你
更新1:30/06/2018 @ 8:16 UTC + 2
在更新了应用程序见解以更紧密地监视垃圾收集之后,我发现性能大打折扣。首先,这是在GC中花费的平均时间百分比:
平均大约有4.5%的时间(但在此期间夜间处于非活动状态),平均大约有10%的时间偷看。然后,我想可视化应用程序处于GC模式的最长时间,而我几乎掉下了椅子:
这可能是错误的图像。但这说明我们的代码必须等待很多时间!我们确实必须解决此问题。
让我们先学习一些适合几代人的东西:
第 0 代。这是最年轻的一代,包含短暂的对象。短期对象的一个例子是临时变量。垃圾收集在这一代中发生得最为频繁。
新分配的对象形成新一代对象,并且隐式为第 0 代集合,除非它们是大对象,在这种情况下,它们位于第 2 代集合中的大对象堆上。
大多数对象在第 0 代中被回收用于垃圾收集,并且不会保留到下一代。
第 1 代。这一代包含短寿命对象,并充当短寿命对象和长寿命对象之间的缓冲区。
第2代。这一代包含长寿命的对象。长寿命对象的一个示例是服务器应用程序中的对象,该对象包含在进程持续时间内有效的静态数据。
在垃圾收集中未回收的对象称为幸存者,并被提升到下一代。在第 0 代垃圾回收中幸存下来的对象将提升到第 1 代;在第 1 代垃圾回收中幸存下来的对象将提升到第 2 代;在第 2 代垃圾回收中幸存下来的对象仍保留在第 2 代中。
当垃圾收集器检测到一代中的生存率较高时,它会增加该一代的分配阈值,因此下一次收集会获得大量的回收内存。CLR 不断平衡两个优先级:不让应用程序的工作集变得太大,以及不让垃圾收集花费太多时间。
临时段的大小取决于系统是 32 位还是 64 位以及它运行的垃圾收集器的类型。默认值如下表所示。
| 32位 | 64位 | |
|---|---|---|
| 工作站气相色谱 | 16MB | 256MB |
| 服务器GC | 64MB | 4GB |
| 具有 > 4 个逻辑 CPU 的服务器 GC | 32MB | 2GB |
| 具有 > 8 个逻辑 CPU 的服务器 GC | 16MB | 1GB |
临时段可以包括第二代对象。第 2 代对象可以使用多个段(根据进程需要和内存允许的数量)。
从临时垃圾回收中释放的内存量仅限于临时段的大小。释放的内存量与死亡对象占用的空间成正比。
参考:https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals