首页 > 解决方案 > “指示托管堆垃圾收集的开始”到底是什么意思,它是坏的吗?

问题描述

究竟是做什么的

指示托管堆垃圾回收的开始

意思是,这很糟糕吗?

在运行 Visual Studio 调试器时,我正在查看进程内存,当我的一项操作发生时,进程内存图中有许多黄色符号,表示许多“指示托管堆垃圾收集的开始”发生了操作。代码在合理的时间内处理,所以这是一件坏事吗?

标签: c#visual-studiodebugginggarbage-collection

解决方案


“指示托管堆垃圾收集的开始”是什么意思?

CLR 有一个垃圾收集器。它跟踪正在使用的内存量,当它的启发式方法表明现在可能是尝试回收未使用内存的好时机时,它会收集垃圾内存并释放它。这样做会压缩堆。

不好吗?

根据您使用的 CLR 版本及其配置方式,有多种不同的垃圾回收策略。其中一些是“阻止世界”的收藏家;也就是说,当收集发生时,您的程序会暂停几毫秒。 如果您的程序需要实时或近乎实时地处理时间预算少于几毫秒的事件,那么在错误的时间收集可能会非常糟糕

例如,假设您正在编写代码来分析以每秒数千米的速度移动的来袭导弹的飞行路径,并触发一些对策。如果由于在错误的时间进行垃圾收集而导致错误几毫秒,那么您的分析可能会偏离几米,并且您可能会错过目标。 不要用 C# 编写软件来运行导弹拦截系统。人可能会死。这真的很糟糕。

例如,假设您正在编写一个每秒刷新 60 次屏幕的游戏。这使您每次刷新不到 17 毫秒即可完成所有必要的游戏计算。如果这样做需要 14 毫秒,那么垃圾收集可能会导致您错过一帧。游戏玩家可能会被激怒。这真的很糟糕。

例如,假设您正在编写更新数据库的业务线软件,并且需要十秒钟来更新数据库。垃圾收集可能会中断它,然后可能需要十秒加三毫秒。这还不错。没关系。

从用户体验性能的角度分析您的应用程序,设置性能预算,并验证垃圾收集是否使您保持在预算范围内。如果您在垃圾收集方面没有预算,那么您需要使用特殊技术来控制执行收集的方式和时间,以确保它们在预算范围内发生。

特别是,如果您超出了收款的性能预算,那么您必须管理收款压力。“压力”是 GC 用来决定何时收集的启发式;它是最近分配了多少内存、分配的大小、内存存活了多少集合以及许多其他因素的组合。

当我们设计 Roslyn(当前这一代 C# 编译器技术)时,我们必须非常小心地管理收集压力,因为编译器会在编辑器中的击键之间进行许多小分配。在某些情况下,由于不需要的集合,我们没有足够快地进行分析以在键入期间产生 IntelliSense 行为。我们使用了多种技术来减少压力,以及收集器在收集期间移动内存所必须做的工作量。

这些都是先进的技术。如果您在预算范围内,请不要担心它们。但是,在您制定预算并衡量您是否在预算内之前,您不会知道自己是否在预算内!


推荐阅读