2009-05-27 70 views
0

我写了一个小型的内部C#程序,它在各种文件格式之间批量转换,主要依赖于其他API。目前,UI生成一个BackgroundWorker(不是线程)来处理转换,然后用作为工作者完成作业时清空的请求填充队列。队列对象本身非常小(3个字符串,告诉工作人员该做什么),并且对程序的内存占用量没有太大贡献。我的内存管理非常严格(完成后丢弃图像,并在某些时候手动进行垃圾收集)。但是,程序一次只能使用大约100 MB的内存,并且占用了大约50%的内存总CPU时间。这似乎是如果我天真地执行线程,它会很快用完系统内存(除非CLR做了某种我不知道的魔法)。防止多线程应用程序内存不足

是否有一种简单/有效的方法来产生线程来防止除了捕获OutOfMemory异常并回滚已死的线程(似乎效率很低,但没有办法在不使用大量内存的情况下保留状态)之外,系统还会耗尽内存。

+2

我们在说多少个话题?你提到UI和一名工作人员......但这不应该是一个大问题;你是否会产生很多线程? – 2009-05-27 20:30:42

回答

2

如果您使用ThreadPool.QueueUserWorkItem产生转换,您将自动获得正在运行的线程数的限制。 ThreadPool在内部进行管理,并在池线程可用时立即处理排队调用。

0

对队列大小设置限制,并使发送者等待已满。但是,您必须凭经验找到正确的队列大小限制。

0

内存不足异常可能会非常棘手,可能由内存碎片引起,而不是实际内存不足。因此,他们可能很难追查。

来自Sweeden的微软产品支持Tess(http://blogs.msdn.com/tess/)已经获得了很多关于追踪内存的帖子,内存将帮助这个过程。

您的应用程序的良好形象也可以帮助。 JetBrains和AQTime一样都很好。

0

使用100MB内存对于图像处理应用程序并不是很多。

另外,在.net中,当你得到一个OutOfMemory异常时,整个过程就会消失,你无法从中恢复。

如果你需要更多的内存(或者更准确的说,更多的地址空间),那么当你使用它或者切换到64位时,系统可以给你任意页面内存。

您可以限制队列大小以确保唯一的“重”内存用户是工作者线程,可以有多个工作线程,这会增加内存使用量,但也会更快地清空队列,只记得在像这样的CPU密集型操作中具有比CPU核更多的线程是低效的。

你说的是“天真实现的线程”,多线程充满了陷阱 - 一个天真的实现将效率低下,充满了错误。