【问题标题】:For Loop - Out of Memory ExceptionFor 循环 - 内存不足异常
【发布时间】:2014-08-01 02:01:30
【问题描述】:

实际上,我得到了像save in Db 和combinations of 9 digit number 这样的加密格式的要求。

所以,我使用了一种非常基本的加密算法,并考虑使用 for 循环直到 999,999,999 并将记录保存在 DataTable 和 BulkCopy to SQL 中。

我的程序是这样的:

DataTable DtData = new DataTable();
DtData.Columns.Add("ENCRYPTED_DATA", typeof(string));        

for (Int64 i = 1; i <= 999999999; i++)
{
    string Number = i.ToString("D9");

    string Encrypt = EncryptDecrypt.Encrypt(Number);

    DtData.Rows.Add(Encrypt);

    if (i % 100000 == 0)
    {
        GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
    }
}

但我的问题是我在一段时间后收到out of memory exception。
有没有办法Garbage Collect 或其他方式来节省内存消耗?
实际上GC.Collect 的代码并没有减少我在TaskManager 中看到的内存使用量。

我的PC RAM is 16GB 和处理8,000,000 records is 7 minutes 所需的大致时间。
消耗 16GB 后,它会根据 TaskManager 发出 OutOfMemoryException。
有没有办法减少 MemoryConsumption 并使我的 forloop 完全执行?

【问题讨论】:

  • 内存不足是因为内存不足。你在期待什么??

标签: c# for-loop memory-management garbage-collection out-of-memory


【解决方案1】:

线

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

不会释放DataTable DtData 中已有的数据。我不知道您正在创建的字符串的大小,但您正在创建数千个字符串并将它们添加到DataTable DtData。

DtData 中的这些字符串永远不符合此循环范围内的垃圾回收条件。

您应该定期将数字提交到数据库,如下所示

DataTable DtData = new DataTable();
DtData.Columns.Add("ENCRYPTED_DATA", typeof(string));        

for (Int64 i = 1; i <= 999999999; i++)
{
    string Number = i.ToString("D9");

    string Encrypt = EncryptDecrypt.Encrypt(Number);

    DtData.Rows.Add(Encrypt);

    //vary this number depending on your performance testing and application needs
    if (i % 100000 == 0)
    {
        //instead of this 
        //GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);


        //commit changes and refresh your DataTable

        DoSomeDatabaseCommitHere(DtData);
        DtData = new DataTable();

    }
}

您也可以使用Collection class - MSDN 代替DataTable 以获得更多选项和异步上传。

【讨论】:

  • 是的。我要去试试。谢谢你的支持
  • 据我计算,完成整个周期需要 17 多个小时。有没有办法让它快速?代替DataTable,如果我使用List,会有帮助吗?
  • 列表应该更快,尽管 HashSet 可能性能更高。有关 List 与 HashSet 的更多信息,请参阅stackoverflow.com/questions/150750/hashset-vs-list-performance。可能还将行 if (i % 100000 == 0) 修改为更大的数字以减少批量提交。此外,您可以查看在加密时使用后台线程进行提交。请参阅我的链接,了解有助于解决此问题的各种 Collection 类。
【解决方案2】:

您的 DtData 正在填满并占用您所有的内存。

世界上所有的垃圾收集都无济于事。

不时将数据保存到数据库并清空 DtData 数据表。

【讨论】:

  • ok。将尝试在 if (i % 100000 == 0) 条件下将记录保存到 DB 并清除 DataTable。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-05
  • 1970-01-01
相关资源
最近更新 更多