实际上,我的加密格式是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完全执行?
答案 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。