在过去的几天里,我一直试图在应用程序中识别内存泄漏。我有充分的理由相信它来自这段代码;Parallel.Invoke()可能的内存泄漏?
List<Item> Items = new List<Item>();
List<Action> Actions = new List<Action>();
while (true)
{
//The queue is a singleton which is used by multiple threads.
//This method grabs the lock and dequeues 500 items at a time.
Items = ItemQueue.Instance.DequeuePackageByAmount(500);
if (Items == null) break;
for (int i = 0; i < Items.Count; i++)
{
int copy = i;
Actions.Add(new Action(() => DoSomethingWithItem(Items[copy])));
}
Parallel.Invoke(new ParallelOptions { MaxDegreeOfParallelism = 500 }, Actions.ToArray());
Items.Clear();
Actions.Clear();
}
Item
不包含任何应该丢弃的未管理资源。为了完整性;
public class Item
{
public ICollection<string> SomeCollection;
public string SomeString;
}
而且,当然;
public void DoSomethingWithItem(Item item)
{
ItemProcessor processor = new ItemProcessor();
processor.Process(item);
}
public class ItemProcessor
{
private DbContextWrapper db;
public ItemProcessor()
{
//DbContextWrapper contains methods which talk to the database.
//Every method has a using(), so there should be no DbContext resources
//left undisposed.
db = new DbContextWrapper();
}
public void Process(Item item)
{
foreach(string s in item.SomeCollection)
{
//check some things and push it to the next queue if valid
}
}
}
我知道我不应该问请找内存泄漏因为代码是伪。因此;
是否有可能这段代码易受内存泄漏的影响,如果是,哪里?
编辑1:
为了进一步解释我有充分的理由相信,它来自这一段代码;我已经测试了几块代码,这块是分配最多内存的块。大约5分钟后,我的应用程序使用大约1.6G RAM,不久之后,它崩溃了OutOfMemoryException
。
此外,为了进一步解释DbContextWrapper
,它看起来像这样;
AFAIK,这种方式应该没有非托管资源留下不处理。
你可以看看你的代码几个小时......或者你可以创建内存转储和分析它。你试过了吗?或者你可以使用内存分析器 - 你试过了吗? – 2014-11-21 11:41:28
你说*我有充分的理由相信它来自这段代码*和How?你有没有介绍你的申请? – 2014-11-21 11:42:50
在MaxDOP中指定500不会运行得更快,它只会导致492个不活动的任务,假设您有一个带有超线程的四元代码。为什么你想为每个项目运行不同的操作,而不是仅仅对数据执行一个Parallel.ForEach?您无故创建500名代表。 – 2014-11-21 11:44:18