Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
创建大量对象时内存不足C#_C#_Linq To Sql_Memory_Object_Out Of Memory - Fatal编程技术网

创建大量对象时内存不足C#

创建大量对象时内存不足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&

我正在我的应用程序中处理一百万条记录,我从MySQL数据库中检索这些记录。为此,我使用Linq获取记录,并使用.Skip()和.Take()一次处理250条记录。对于每个检索到的记录,我需要创建0到4个项,然后将它们添加到数据库中。因此,平均需要创建的项目总数约为200万个

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