持久化队列以防止C#中出现内存不足错误

时间:2009-02-07 05:31:04

标签: c# .net data-structures

我有数据结构,特别是一个队列,它越来越大,导致内存不足异常。由于它所持有的相对性简单对象(具有基本上一个字符串字段),这是意外的行为。

是否有一种简单的方法或内置的.NET方法将此集合保存到磁盘上的文件中(没有可以使用的数据库),它是否继续透明地作为队列运行?

5 个答案:

答案 0 :(得分:3)

对于您的问题,队列可能不是合适的数据结构。队列中有多少个对象?你真的需要存储所有这些字符串以供日后使用吗?你能用像枚举更小的东西或像Flyweight design pattern那样面向对象的东西替换字符串吗?

如果您正在处理大量数据,有时重新计算或重新加载原始数据比保存副本以供日后使用更快。或者您可以在加载数据时处理数据,并避免将其保存以供以后处理。

答案 1 :(得分:2)

我会首先调查为什么你正在获得OOM。

如果要添加到队列中 - 请检查大小并在违反阈值时执行某些操作。

你可以过滤这些物品吗?这些物品有很多重复吗?在这种情况下,您可以使用预先缓存的对象替换重复项。

答案 2 :(得分:1)

我会使用Sqlite将数据保存到磁盘。

答案 3 :(得分:0)

在回答您对该问题的评论时,我猜您可以将文件收集线程拆分为两个线程:

  • 第一个线程仅计算要处理的文件数,并增加volatile int count。该线程仅更新计数;它不会在队列中存储任何内容。
  • 第二个线程与第一个线程非常相似,只是它没有更新计数,而是实际上将数据保存到队列中。当队列的大小达到某个阈值时,您的线程应该阻塞一段时间,然后继续将数据添加到队列中。这可确保您的队列永远不会超过某个阈值。

我甚至猜你实际上不需要第二个线程。由于第一个将为您提供所需的计数,您可以在主线程中找到实际文件,一次一个文件。这样你就可以避免拥有队列,这将减少你的内存需求。

但是,我怀疑你的队列是你出现内存异常的原因。即使你在队列中添加了一百万个条目,这也只需要大约512 MB的内存。我建议你检查你的处理逻辑。

答案 4 :(得分:0)

具体答案是否定的,没有简单或内置的方法来做到这一点。你必须把它写在磁盘上“你自己”。

弄清楚为什么你会因为内存不足而感到惊讶。也许是它的字符串internment,也许你正在使用所有小对象分配来分割GC。来自微软的CLR Profiler非常棒。