我创建了一个由4个块组成的数据流管道(包括一个可选块),它负责通过HTTP从我的应用程序接收查询对象,从数据库中检索信息,对该数据进行可选转换,以及然后将信息写回HTTP响应中。
在我做过的一些测试中,我已经从数据库(57万行)中提取了大量数据,这些数据存储在List对象中并在不同的块之间传递,看起来甚至在最终之后块已经完成,内存未被释放。任务管理器中的Ram使用量将增加到2 GB以上,当List命中每个块时,我可以观察到几个大的峰值。
我的块的签名如下所示:
private TransformBlock<HttpListenerContext, Tuple<HttpListenerContext, QueryObject>> m_ParseHttpRequest;
private TransformBlock<Tuple<HttpListenerContext, QueryObject>, Tuple<HttpListenerContext, QueryObject, List<string>>> m_RetrieveDatabaseResults;
private TransformBlock<Tuple<HttpListenerContext, QueryObject, List<string>>, Tuple<HttpListenerContext, QueryObject, List<string>>> m_ConvertResults;
private ActionBlock<Tuple<HttpListenerContext, QueryObject, List<string>>> m_ReturnHttpResponse;
它们的链接如下:
m_ParseHttpRequest.LinkTo(m_RetrieveDatabaseResults);
m_RetrieveDatabaseResults.LinkTo(m_ConvertResults, tuple => tuple.Item2 is QueryObjectA);
m_RetrieveDatabaseResults.LinkTo(m_ReturnHttpResponse, tuple => tuple.Item2 is QueryObjectB);
m_ConvertResults.LinkTo(m_ReturnHttpResponse);
我是否可以设置管道,这样一旦每个块完成列表,它们就不再需要保持它,以及整个管道完成后释放内存?
答案 0 :(得分:1)
数据流块没有理由保存对已处理消息的引用。因此,我相信他们不这样做。如果他们确实这样做,那么我认为这是一个你应该报告的错误。
任务管理器中报告的大RAM使用率并不一定意味着未收集对象。这也可能意味着框架尚未将GCed内存返回给操作系统。我相信当你有足够的可用内存时,框架对于返回内存非常懒惰,因为没有充分的理由这样做。
您应该做的是使用更合适的工具。例如,您可以使用.Net性能计数器来非常密切地监视GC。您还可以使用内存分析器查看有关内存使用情况的更多详细信息,如果实际上有内存泄漏,则会导致内存使用情况。