Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#垃圾回收导致应用程序性能下降?_C#_Performance_Garbage Collection - Fatal编程技术网

C#垃圾回收导致应用程序性能下降?

C#垃圾回收导致应用程序性能下降?,c#,performance,garbage-collection,C#,Performance,Garbage Collection,我的应用程序一整天都在运行,性能会下降 我怀疑它是垃圾收集器,如何验证? 有没有办法找出哪个对象/函数导致了垃圾收集开销 有没有办法通过编程手动执行垃圾收集以清除内存泄漏 谢谢 编辑 在应用程序的一端,它接收来自非托管api的回调以接受数据、处理数据,然后在第二端从套接字发送消息。然后,它从第二个终端返回发送的消息的后续数据。 应用程序打开5-6个套接字以从第二端发送和接收数据。 它在一个单独的线程上不断地将大量数据记录到windows文件系统中 我的测量包括发送数据之前的时间戳(querype

我的应用程序一整天都在运行,性能会下降

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

有没有办法通过编程手动执行垃圾收集以清除内存泄漏

谢谢

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

我的测量包括发送数据之前的时间戳(queryperformance计数器),以及从套接字上的另一个进程接收后续操作时的时间戳。 我注意到,在我打开的多个插座中,性能恶化只发生在一个插座连接上

时间戳和通过套接字发送接收数据之间的处理包括迭代2个arraylist,该arraylist包含不超过5-6个对象和两个回调

“任务管理器”窗口中的内存使用量没有显著增加。运行6-7小时后从96MB变为100MB

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

“最终化幸存者”和“从第0代开始提升终结记忆”随时间逐渐增加

“第0代系列”从最初的1819年发展到4小时后的6000年。 “第1代收集”是第0代收集的10%-12%,而“第2代收集”是1%或更少。考虑到第0代收集数量是累积的,这可能不是abig关注的问题


GC句柄“从850ish增加到4000。

更有可能是内存泄漏,手动调用GC也无济于事:如果代码没有释放对象,它就无法处理对象

编辑

由于您的GC句柄不断增加,这表明有一些非托管资源无法释放。例如,我在位图中遇到过这种情况,但您可能需要告诉我们更多关于您的应用程序的信息,以获得更具体的建议


这可能会给您一些有用的见解。

您可以调用
GC.Collect()
强制垃圾收集,但这不会修复内存泄漏。请尝试使用诸如ANTS memory profiler之类的内存探查器来查找内存泄漏


这可能不一定是内存问题。使用Windows性能监视器(查找管理工具)来监视应用程序的CPU、内存、GDI对象计数、句柄计数,并查看在应用程序的整个生命周期中是否有任何这些值在上升

通常,您会发现您正在使用System.Drawing中的某些内容,而没有调用Dispose()在它上面,导致句柄泄漏。我发现句柄泄漏往往比内存泄漏更快地影响性能。而句柄泄漏不会导致GC压力,这意味着你可能像筛子一样泄漏句柄,GC永远不会知道其中的区别


因此,长话短说:测量,测量,测量。然后你就会知道要修复什么。

通常调用
GC.Collect()
的可能重复是个坏主意,因为垃圾收集器通常比你(或开发人员)做得更好但是,对于某些特定的需要,像独立的COM服务器一样,这是管理引用生存期的唯一方法,因为它需要被管理。另外,如果您在内存中设置了许多临时内容以便对它们执行操作,然后存储结果,调用
GC.Collect()
如果循环足够快,将有帮助。我遇到OOM问题,因为GC发生得不够快,但我必须进行分析,以知道这实际上会帮助我解决问题。我会在“任务管理器”中看到“内存使用”上升吗“如果内存泄漏,进程窗口?是的,如果有足够的内存泄漏,您肯定会这样做。因此,内存使用量仅从96MB增加到100MB。性能计数器显示“Gen 0 collections”从开始时的1819增加到4小时后的6000。”。“Gen 1集合”占Gen 0集合的10%-12%,而“Gen 2集合”占1%或更少。“GC句柄”从850ish增加到4000。有没有其他柜台我应该找?。添加计数器是否会导致开销?@bsobaid:是否会导致可观的开销值得怀疑。您已经遇到了性能问题,您不妨花一天时间进行测量,以发现问题的根源。