GC终结器队列中有大量对象

本文关键字:对象 队列 GC | 更新日期: 2023-09-27 18:26:43

我正在调查我们的服务器.NET应用程序内存占用的缓慢而稳定的增加。为了便于调查,我对6个模拟真实负载的客户端进行了压力测试,这些客户端一遍又一遍地重复相同的使用模式。当我通宵跑步时,我可以看到内存占用增加了大约几百MB。在分析和比较相隔12小时的服务器内存快照后,发现大部分差异是由于ReaderWriterLock实例在终结器队列中等待造成的。他们有超过6000000人!?!

分析我的代码并查看GC根可以发现,所有ReaderWriterLock活动实例都来自我们软件中的DataSet实例。因此,我对DataSet实例的创建进行了研究,试图尽可能地消除它。在清理了一些代码并缓存了一些DataSet实例以避免不必要的分配后,差异减少了约25%,但看起来还有更多。

我的问题是:

  1. 为什么终结器队列中有这么多实例——不确定是什么原因导致的
  2. 我认为终结器队列的大小可能会对GC和整个应用程序性能产生负面影响(过一段时间后,我觉得它看起来很慢)
  3. 我应该怎么做才能减少终结器队列的大小?对我不再需要的每个DataSet实例调用dispose

请注意,我使用的是"服务器"模式GC,因为我们的服务器在不同的线程上并行处理请求。

GC终结器队列中有大量对象

虽然我还没有弄清楚为什么终结器队列中有这么多ReaderWriterLock实例,但我确实找到了解决问题的方法并将它们处理掉了。

调用DataSet.Dispose没有帮助。因此,我已经开始重用现有的DataSet实例,而不是不断创建新的实例,因为"有人说DataSet.Clear很慢"——从长远来看,它不是(如果有的话)。这种方法完全消除了终结器队列实例的问题。