我有一个简单的生产者/消费者模式,生产者每 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
}
}
现在我将解释我的问题:
在这几秒钟中,我产生了大约50.000条数据记录,所有数据都必须存储在数据库中。该应用程序大约需要1分钟才能完成此工作。
问题所在::即使所有数据记录都存储在数据库中(即queue.count == 0
),应用程序的内存使用量也没有减少!
此应用程序必须运行24/7,并存储数百万条数据记录。因此,几分钟/小时后,我将耗尽内存。 (据我计算,在30分钟后会有一个生产中断,所有数据都应出队,如果内存使用量减少,它就可以工作。)
为什么将每个项目从队列中取出后,内存不会减少?
我测试了这个应用程序很多小时,并且内存消耗来自
_queue.Enqueue(data);
行。因此,我100%确信,没有其他代码行负责内存使用。
即使我在使所有项目出队后使用queue.clear();
或强制使用GB.collect();
,内存使用情况仍然看起来像这样:
有人可以向我解释C#中Queue或ConcurrentQueue的内存使用情况吗?
为什么将所有项目出队后它不会减少?
提前谢谢