试图了解ConcurrentQueue <t>的内存消耗

时间:2018-07-13 06:18:40

标签: c# memory-management memory-leaks queue

我有一个简单的生产者/消费者模式,生产者每 1毫秒产生一次数据。使用者每隔 3毫秒使用一次数据。因此,我需要一个队列来临时存储数据。直到现在一切都很好。

队列填充以下代码:

private ConcurrentQueue<string> _queue = new ConcurrentQueue<string>();

public void enqueueData(string data)
{
    _queue.Enqueue(data);
}

然后我有一个线程,该线程使用数据(数据必须存储在数据库中-存储一条记录大约需要3ms的时间)

private Thread _consumerThread;

在此类的构造函数中,我将在存储第一条记录时启动Thread以使用数据。直到现在都很简单。

public Consumer()
{
    _consumerThread = new Thread(new ThreadStart(consumeData));
    _consumerThread.Start();
}

以下方法将使用数据并将其存储在数据库中

private string _resultData = null;
private object _lock = new object();

private void consumeData()
{
    while(true)
    {
        while(_queue.Count > 0)
        {
            _resultData = null;
            if (_queue.TryDequeue(out _resultData))
            {
                lock(_lock)
                {
                    DataHandler.processData(_resultData); // this does the database stuff
                }
            }
        }
        Thread.Sleep(_sleeptime); // sleep 50ms 
    }
}

现在我将解释我的问题:

  • 应用程序启动时,内存使用情况如下所示:

enter image description here

  • 生成数据几秒钟后,它看起来如下:

enter image description here

在这几秒钟中,我产生了大约50.000条数据记录,所有数据都必须存储在数据库中。该应用程序大约需要1分钟才能完成此工作。

问题所在::即使所有数据记录都存储在数据库中(即queue.count == 0),应用程序的内存使用量也没有减少!

此应用程序必须运行24/7,并存储数百万条数据记录。因此,几分钟/小时后,我将耗尽内存。 (据我计算,在30分钟后会有一个生产中断,所有数据都应出队,如果内存使用量减少,它就可以工作。)

为什么将每个项目从队列中取出后,内存不会减少?

我测试了这个应用程序很多小时,并且内存消耗来自 _queue.Enqueue(data);行。因此,我100%确信,没有其他代码行负责内存使用。

即使我在使所有项目出队后使用queue.clear();或强制使用GB.collect();,内存使用情况仍然看起来像这样:

enter image description here

有人可以向我解释C#中Queue或ConcurrentQueue的内存使用情况吗?

为什么将所有项目出队后它不会减少?

提前谢谢

0 个答案:

没有答案