C#应用程序性能因垃圾回收而恶化?

时间:2010-10-26 21:59:24

标签: c# performance garbage-collection

我的应用程序的性能会随着持续一整天而恶化。

我怀疑它是垃圾收集器,我该如何验证呢? 有没有办法找出哪个对象/函数导致垃圾收集开销?

有没有办法以编程方式手动执行垃圾收集以清除泄漏记忆?

谢谢,

修改 在应用程序的一端,它接收来自非托管api的回调以接受数据,处理它,然后在第二端从套接字发送消息。然后从第二端获取有关其发送的消息的后续数据。 应用程序打开5-6个套接字以从第二端发送和接收数据。 它不断地在一个单独的线程上将大量数据记录到Windows文件系统。

我的测量包括在我发送数据之前的时间戳(queryperformance counter)和当我从套接字上的另一个进程接收后续时间时再次使用timestampinga。 我注意到我打开了多个插槽,性能下降只发生在一个套接字连接上。

socket上的timestamping和sending.receiving数据之间的处理包括迭代2个arraylist,它不超过5-6个对象和几个回调。

Task MAnager窗口的内存使用量不会大幅增加。运行6-7小时后,从96MB到100MB。

以下是运行perfmon的一些观察结果。

“金融化幸存者”和“从第0代晋升终结记忆”逐渐增加

“Gen 0 collection”从开始时的1819年开始到4小时后的6000。 “Gen 1 Collections”是Gen 0集合的10%-12%,“Gen 2集合”是1%或更少。第0代收集号码是累积的,可能不会引起人们的关注。

GC处理“从850上升到4000.

3 个答案:

答案 0 :(得分:4)

您更有可能发生内存泄漏,并且手动调用GC无助于此:如果您的代码尚未释放,则无法处置对象。

修改

由于GC句柄越来越多,this page表明存在未被释放的非托管资源。例如,我在位图中遇到过这种情况,但您可能需要告诉我们更多有关您的应用程序以获得更具体的建议。

Here's a thread可能会为您提供一些有用的见解。

答案 1 :(得分:4)

您可以调用GC.Collect()来强制进行垃圾回收,但这不会解决内存泄漏问题。尝试使用像ANTS内存分析器这样的内存分析器来查找内存泄漏。

ANTS memory profiler

答案 2 :(得分:2)

它可能不一定是内存问题。使用Windows性能监视器(查看管理工具)来监视应用程序的CPU,内存,GDI对象计数,句柄计数,以及在应用程序的整个生命周期中是否显示其中任何一个似乎都在攀升。

通常,您会发现您正在使用System.Drawing中的某些内容而不是在其上调用Dispose(),从而导致句柄泄漏。我发现手柄泄漏往往比内存泄漏更快地消耗性能。并且处理泄漏不会导致GC压力,这意味着您可能会像筛子一样泄漏手柄,并且GC不会知道其中的差异。

所以,长话短说:衡量,衡量,衡量。然后你会知道要解决什么。