问题描述
大约有 1000 个任务正在运行,但有时我会收到以下任务调度程序抛出的内存不足异常.可能是什么原因以及如何避免.
There around 1000 task running but sometimes i receive the following aout of memory exception thrown by task scheduler.What could be the reason and how to avoid it.
System.Threading.Tasks.TaskSchedulerException: An exception was thrown by a TaskScheduler. ---> System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Threading.Thread.StartInternal(IPrincipal principal, StackCrawlMark& stackMark)
at System.Threading.Thread.Start(StackCrawlMark& stackMark)
at System.Threading.Thread.Start(Object parameter)
at System.Threading.Tasks.ThreadPoolTaskScheduler.QueueTask(Task task)
at System.Threading.Tasks.Task.ScheduleAndStart(Boolean needsProtection)
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ScheduleAndStart(Boolean needsProtection)
at System.Threading.Tasks.Task.InternalStartNew(Task creatingTask, Object action, Object state, CancellationToken cancellationToken, TaskScheduler scheduler, TaskCreationOptions options, InternalTaskOptions internalOptions, StackCrawlMark& stackMark)
at System.Threading.Tasks.TaskFactory.StartNew(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions, TaskScheduler scheduler)
at App.StartReadSocketTask()
推荐答案
您的(非 x64)应用程序的最大内存空间为 2GB.每个线程至少需要 1 MB,通常您可以在达到 1000 个线程之前预期 OOM.
Your (non x64) App has a max memory space of 2GB. Each Thread requires a minimum of 1 MB, typically you can expect OOM before you reach 1000 Threads.
Task 类本身应该解决这个问题(通过使用 ThreadPool).但是当您的任务花费太长时间(> 500 毫秒)时,TP 将缓慢添加线程,在几分钟或更长时间后失败.
In itself the Task class is supposed to address this (by using the ThreadPool). But when your Tasks take too long (> 500 ms) the TP will slowly add Threads, failing after a few minutes or longer.
最简单的解决方案可能是查看您的代码中发生这种无限制创建任务的地方,看看您是否可以以与您的解决方案一致的方式进行限制.就像您使用生产者/消费者队列一样,将其设为有界队列.
The simplest solution might be to look in your code where this unbounded creation of Tasks occurs, and see if you can limit in a way that agrees with your solution. Like if you are using a Producer/Consumer Que, make it a bounded queue.
否则,请限制 MaxThreads,但这是一个生硬的、应用程序范围的工具.
Otherwise, limit the MaxThreads but this is a blunt, application-wide instrument.
这篇关于TaskFactory.StartNew ->System.OutOfMemoryException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!