究竟是什么
指示托管堆垃圾收集的开始
意思是,这很糟糕吗?
在运行Visual Studio调试器时,我正在查看进程内存,并且当我执行一项操作时,进程内存图中有许多黄色符号,表示许多“表示托管堆的开始”垃圾回收”操作已发生。代码在合理的时间内处理,这是一件坏事吗?
答案 0 :(得分:7)
“指示托管堆垃圾收集的开始”是什么意思?
CLR有一个垃圾收集器。它跟踪正在使用的内存量,并且当其启发式指示现在可能是尝试回收未使用的内存的好时机时,它将收集垃圾内存并释放它。这样可以压缩堆。
不好吗?
有多种不同的垃圾回收策略,具体取决于您所使用的CLR版本及其配置方式。他们中的一些人是“阻止世界”的收藏家。也就是说,在进行收集时,您的程序会暂停几毫秒。 如果您的程序需要对事件进行实时或近乎实时的处理,且时间预算少于几毫秒,那么在错误的时间进行收集可能会很糟糕。
例如,假设您正在编写代码以分析以每秒数千米的速度移动的传入导弹的飞行路径,并触发一些对策。如果由于在错误的时间进行了垃圾收集而在几毫秒内弄错了,您的分析可能会偏离几米,您可能会错过目标。 请勿编写用于在C#中运行导弹拦截系统的软件。人们可能会死。真的很糟糕。
例如,假设您正在编写一个游戏,该游戏每秒刷新屏幕60次。这样,每次刷新您不到17毫秒即可完成所有必要的游戏计算。如果这样做需要14毫秒,那么垃圾回收可能会导致您错过一帧。玩家可能会感到恼火。真的很糟糕。
例如,假设您正在编写业务更新软件,该软件将更新数据库,并且需要十秒钟来更新数据库。垃圾回收可能会中断该过程,然后可能需要十秒钟再加上三毫秒。不错很好。
从用户体验性能的角度分析应用程序,设置性能预算,并验证垃圾收集是否使您的预算保持在预算之内。如果您没有预算进行垃圾回收,则需要使用特殊技术来控制垃圾回收的方式和时间,以确保垃圾回收在预算内发生。
尤其是,如果您的预算超出了绩效预算,那么您就必须应对预算压力。 “压力”是GC用于确定何时收集的启发式方法;它是最近分配了多少内存,分配的大小,内存可以存活多少个集合以及许多其他因素的组合。
在设计Roslyn(当前的C#编译器技术)时,我们必须非常小心地管理集合压力,因为编译器会在编辑器的击键之间进行许多小的分配。在某些情况下,由于不想要的集合,我们在输入期间无法快速进行分析以产生IntelliSense行为。我们使用了多种技术来降低压力,并降低收集器在收集期间移动内存所需的工作量。
这些是高级技术。如果您的预算有限,请不要担心。但是,在制定预算并衡量是否在预算之内之前,您不会知道自己是否在预算中!