创建大量对象时内存不足C#
我正在我的应用程序中处理一百万条记录,我从MySQL数据库中检索这些记录。为此,我使用Linq获取记录,并使用.Skip()和.Take()一次处理250条记录。对于每个检索到的记录,我需要创建0到4个项,然后将它们添加到数据库中。因此,平均需要创建的项目总数约为200万个创建大量对象时内存不足C#,c#,linq-to-sql,memory,object,out-of-memory,C#,Linq To Sql,Memory,Object,Out Of Memory,我正在我的应用程序中处理一百万条记录,我从MySQL数据库中检索这些记录。为此,我使用Linq获取记录,并使用.Skip()和.Take()一次处理250条记录。对于每个检索到的记录,我需要创建0到4个项,然后将它们添加到数据库中。因此,平均需要创建的项目总数约为200万个 IQueryable<Object> objectCollection = dataContext.Repository<Object>(); int amountToSkip = 0; IList&
IQueryable<Object> objectCollection = dataContext.Repository<Object>();
int amountToSkip = 0;
IList<Object> objects = objectCollection.Skip(amountToSkip).Take(250).ToList();
while (objects.Count != 0)
{
using (dataContext = new LinqToSqlContext(new DataContext()))
{
foreach (Object objectRecord in objects)
{
// Create 0 - 4 Random Items
for (int i = 0; i < Random.Next(0, 4); i++)
{
Item item = new Item();
item.Id = Guid.NewGuid();
item.Object = objectRecord.Id;
item.Created = DateTime.Now;
item.Changed = DateTime.Now;
dataContext.InsertOnSubmit(item);
}
}
dataContext.SubmitChanges();
}
amountToSkip += 250;
objects = objectCollection.Skip(amountToSkip).Take(250).ToList();
}
IQueryable objectCollection=dataContext.Repository();
int amountToSkip=0;
IList objects=objectCollection.Skip(amountToSkip).Take(250).ToList();
while(objects.Count!=0)
{
使用(dataContext=newlinqtosqlcontext(newdatacontext()))
{
foreach(对象中的对象objectRecord)
{
//创建0-4个随机项
for(int i=0;i
现在,在创建项目时出现了问题。运行应用程序(甚至不使用dataContext)时,内存会持续增加。好像这些东西永远不会被处理掉。有人注意到我做错了什么吗
提前谢谢 我最好的猜测是可能导致内存泄漏的原因。 也许MySQL没有适当的Take/Skip方法实现,而是在内存中进行分页?奇怪的事情发生了,但你的循环看起来很好。所有引用都应超出范围并被垃圾回收 是啊 所以在循环结束时,你会尝试在你的列表中包含200万项,不是吗?在我看来,答案很简单:存储更少的项目或获得更多的内存 --编辑:
可能我看错了,我可能需要编译和测试它,但我现在不能这么做。我将把这个留在这里,但我可能是错的,我没有仔细审查它足够明确,尽管答案可能被证明是有用的,或没有。(从否决票判断,我猜不是:P)
您是否尝试过这样在循环之外声明该项:
IQueryable<Object> objectCollection = dataContext.Repository<Object>();
int amountToSkip = 0;
IList<Object> objects = objectCollection.Skip(amountToSkip).Take(250).ToList();
Item item = null;
while (objects.Count != 0)
{
using (dataContext = new LinqToSqlContext(new DataContext()))
{
foreach (Object objectRecord in objects)
{
// Create 0 - 4 Random Items
for (int i = 0; i < Random.Next(0, 4); i++)
{
item = new Item();
item.Id = Guid.NewGuid();
item.Object = objectRecord.Id;
item.Created = DateTime.Now;
item.Changed = DateTime.Now;
dataContext.InsertOnSubmit(item);
}
}
dataContext.SubmitChanges();
}
amountToSkip += 250;
objects = objectCollection.Skip(amountToSkip).Take(250).ToList();
}
IQueryable objectCollection=dataContext.Repository();
int amountToSkip=0;
IList objects=objectCollection.Skip(amountToSkip).Take(250).ToList();
Item=null;
while(objects.Count!=0)
{
使用(dataContext=newlinqtosqlcontext(newdatacontext()))
{
foreach(对象中的对象objectRecord)
{
//创建0-4个随机项
for(int i=0;i
好的,我刚刚与我的一位同事讨论了这种情况,我们得出了以下有效的解决方案
int amountToSkip = 0;
var finished = false;
while (!finished)
{
using (var dataContext = new LinqToSqlContext(new DataContext()))
{
var objects = dataContext.Repository<Object>().Skip(amountToSkip).Take(250).ToList();
if (objects.Count == 0)
finished = true;
else
{
foreach (Object object in objects)
{
// Create 0 - 4 Random Items
for (int i = 0; i < Random.Next(0, 4); i++)
{
Item item = new Item();
item.Id = Guid.NewGuid();
item.Object = object.Id;
item.Created = DateTime.Now;
item.Changed = DateTime.Now;
dataContext.InsertOnSubmit(item);
}
}
dataContext.SubmitChanges();
}
// Cumulate amountToSkip with processAmount so we don't go over the same Items again
amountToSkip += processAmount;
}
}
int amountToSkip=0;
var finished=false;
当(!完成)
{
使用(var dataContext=new LinqToSqlContext(new dataContext()))
{
var objects=dataContext.Repository().Skip(amountToSkip).Take(250).ToList();
如果(objects.Count==0)
完成=正确;
其他的
{
foreach(对象中的对象)
{
//创建0-4个随机项
for(int i=0;i
在这个实现中,我们每次都会处理Skip()和Take()缓存,因此不会泄漏内存 Ahhh,好老的
InsertOnSubmit
内存泄漏。在尝试使用LINQ to SQL从大型CVS文件加载数据时,我遇到过这种情况,并且多次碰壁。问题是,即使在调用SubmitChanges
之后,DataContext
仍会继续跟踪使用InsertOnSubmit
添加的所有对象。解决方案是在一定数量的对象之后提交更改
,然后为下一批创建新的DataContext
。当旧的DataContext
被垃圾收集时,它所跟踪的所有插入对象(以及您不再需要的对象)也将被垃圾收集
“但是等等!”你说,“创建和处理许多DataContext将有巨大的开销!”。当然,如果您创建一个数据库连接并将其传递给每个DataContext
构造函数,则不会。这样,整个过程中都保持了与数据库的单一连接,DataContext
obje