GC终结器队列中有大量对象
本文关键字:对象 队列 GC | 更新日期: 2023-09-27 18:26:43
我正在调查我们的服务器.NET应用程序内存占用的缓慢而稳定的增加。为了便于调查,我对6个模拟真实负载的客户端进行了压力测试,这些客户端一遍又一遍地重复相同的使用模式。当我通宵跑步时,我可以看到内存占用增加了大约几百MB。在分析和比较相隔12小时的服务器内存快照后,发现大部分差异是由于ReaderWriterLock
实例在终结器队列中等待造成的。他们有超过6000000人!?!
分析我的代码并查看GC根可以发现,所有ReaderWriterLock
活动实例都来自我们软件中的DataSet
实例。因此,我对DataSet
实例的创建进行了研究,试图尽可能地消除它。在清理了一些代码并缓存了一些DataSet
实例以避免不必要的分配后,差异减少了约25%,但看起来还有更多。
我的问题是:
- 为什么终结器队列中有这么多实例——不确定是什么原因导致的
- 我认为终结器队列的大小可能会对GC和整个应用程序性能产生负面影响(过一段时间后,我觉得它看起来很慢)
- 我应该怎么做才能减少终结器队列的大小?对我不再需要的每个
DataSet
实例调用dispose
请注意,我使用的是"服务器"模式GC,因为我们的服务器在不同的线程上并行处理请求。
虽然我还没有弄清楚为什么终结器队列中有这么多ReaderWriterLock
实例,但我确实找到了解决问题的方法并将它们处理掉了。
调用DataSet.Dispose
没有帮助。因此,我已经开始重用现有的DataSet
实例,而不是不断创建新的实例,因为"有人说DataSet.Clear
很慢"——从长远来看,它不是(如果有的话)。这种方法完全消除了终结器队列实例的问题。