我正在开发一个创建交互式图表的程序。但是,即使程序的渲染层被禁用,也会出现以下问题。
在我的应用程序的某些屏幕上,根据Visual Studio 2015诊断工具,GC每秒大约运行4次,从而导致我的应用程序性能下降(从120fps降至15fps)。
我花了一些内存快照,期望看到意外的分配,但根据快照,每隔几秒就只有一两个System.Internal.HandleCollector + HandleType的分配和集合,这似乎是正常的,即使问题是发生了。
我注意到的其他一些事情:
此时我很难过。有没有人看到过这种情况或知道我应该在哪里开始调试?
答案 0 :(得分:4)
来自https://msdn.microsoft.com/en-us/library/ee787088(v=vs.110).aspx
当满足下列条件之一时,就会发生垃圾收集:
系统物理内存较低。
托管堆上已分配对象使用的内存超过了可接受的阈值。在该过程运行时,该阈值会不断调整。
调用GC.Collect方法。几乎在所有情况下,您都不必调用此方法,因为垃圾收集器会持续运行。此方法主要用于独特的情况和测试。
也许您正在满足上面列出的三个条件之一。您的应用程序似乎正在使用大量内存,因此正在运行垃圾收集以尝试清理某些对象以尝试释放一些内存。
也可能GC.Collect()
在您的代码中某处,并导致垃圾收集器再次运行。
Here是与垃圾收集相关的一些故障排除指南。特别是一节似乎涉及到您所遇到的问题。在标记为&#34的部分下;问题:垃圾收集过程中的CPU使用率太高"它说:
垃圾回收期间CPU使用率很高。如果在垃圾收集中花费了大量的处理时间,则收集的数量太频繁或者收集持续时间太长。托管堆上对象的分配率增加会导致垃圾收集更频繁地发生。降低分配率可以减少垃圾收集的频率。
您可以使用Allocated Bytes / second性能计数器监控分配率。有关更多信息,请参阅.NET Framework中的性能计数器。
收集的持续时间主要是分配后存活的对象数量的一个因素。如果仍有许多对象需要收集,垃圾收集器必须经过大量内存。压缩幸存者的工作非常耗时。要确定在集合期间处理了多少对象,请在指定代的垃圾回收结尾处的调试器中设置断点。
答案 1 :(得分:2)
尝试使用此更改app.config并进行运行
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
有关GC的更多有趣详情,请访问https://msdn.microsoft.com/en-us/library/ee787088(v=vs.110).aspx
答案 2 :(得分:0)
您应该检查调用GC的代码。通常它的运行速度远远低于每秒4次。将调试器或分析器附加到有问题的实例,以查找调用GC的位置。也许是在第三方图书馆。或者你想不到的一些代码。