For Loop - Out of Memory Exception

时间:2014-08-01 02:01:30

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

实际上,我的加密格式是save in Db combinations of 9 digit number

因此,我使用了一种非常基本的加密算法,并考虑使用for循环直到999,999,999,并将记录保存在DataTableBulkCopy 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完全执行?

2 个答案:

答案 0 :(得分:2)

该行

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来获取更多选项和异步上传。

答案 1 :(得分:1)

你的DtData正在填满你的所有记忆。

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

立即保存数据,然后保存到数据库并清空DtData DataTable。