1

我创建了一个由 4 个块(包括一个可选块)组成的数据流管道,它负责通过 HTTP 从我的应用程序接收查询对象并从数据库中检索信息,对该数据进行可选转换,然后编写在 HTTP 响应中返回信息。

在我完成的一些测试中,我一直从数据库中提取大量数据(57 万行),这些数据存储在 List 对象中并在不同的块之间传递,看起来即使在最后一个块已经完成之后完成了内存没有被释放。任务管理器中的 Ram 使用量将飙升至 2 GB 以上,当列表命中每个块时,我可以观察到几个大的峰值。

我的块的签名如下所示:

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);

是否有可能我可以设置管道,这样一旦每个块都完成了列表,他们就不再需要保留它,以及一旦整个管道完成,内存就会被释放?

4

1 回答 1

1
  1. 没有理由为什么数据流块应该保存对已处理消息的引用。正因为如此,我相信他们不会那样做。如果他们真的这样做了,那么我认为这是一个你应该报告的错误。

  2. 任务管理器中报告的大 RAM 使用情况并不一定意味着未收集对象。这也可能意味着框架尚未将 GC 内存返回给操作系统。我相信当你有足够的空闲内存时,框架会很懒惰地返回内存,因为没有充分的理由这样做。

    你应该做的是使用更合适的工具。例如,您可以使用 .Net 性能计数器来非常密切地监控 GC。您还可以使用内存分析器来查看有关内存使用情况的更详细信息,如果您确实有内存泄漏,是什么原因造成的。

于 2013-06-27T17:25:30.050 回答