У меня есть процесс загрузки данных, который загружает большой объем данных в DataTable, а затем обрабатывает некоторые данные, но каждый раз, когда задание заканчивается, DataLoader.exe (32 бит имеет ограничение на 1,5 ГБ памяти) не освобождает всю используемую память.DataTable не освобождает память
Я попытался 3 способа, чтобы освободить память:
- DataTable.Clear(), а затем называют DataTable.Dispose() (Release около 800 МБ памяти, но все-таки увеличить 200 МБ памяти каждый раз, когда загрузка данных задания отделки, после того, как 3 или 4 раза больше загрузки данных, из-за исключения из памяти, потому что оно превышает 1,5 Гб памяти)
- Установить значение DataTable в null (освободить память и выбрать загрузку большего количества данных, исключение из памяти)
- вызов DataTable.Dispose() напрямую (освобождение памяти отсутствует, и если вы выбрали загрузку большего количества данных, исключение из памяти исключено)
Ниже приведен код, который я попробовал для тестирования (в реальной программе он не называется рекурсивно, он запускается с помощью некоторой логики просмотра каталога. Этот код предназначен только для тестирования. Извините за сумбур).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace DataTable_Memory_test
{
class Program
{
static void Main(string[] args)
{
try
{
LoadData();
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadKey();
}
}
private static void LoadData()
{
DataTable table = new DataTable();
table.Columns.Add("Dosage", typeof(int));
table.Columns.Add("Drug", typeof(string));
table.Columns.Add("Patient", typeof(string));
table.Columns.Add("Date", typeof(DateTime));
// Fill the data table to make it take about 1 G memory.
for (int i = 0; i < 1677700; i++)
{
table.Rows.Add(25, "Indocin", "David", DateTime.Now);
table.Rows.Add(50, "Enebrel", "Sam", DateTime.Now);
table.Rows.Add(10, "Hydralazine", "Christoff", DateTime.Now);
table.Rows.Add(21, "Combivent", "Janet", DateTime.Now);
table.Rows.Add(100, "Dilantin", "Melanie", DateTime.Now);
}
Console.WriteLine("Data table load finish: please check memory.");
Console.WriteLine("Press 0 to clear and dispose datatable, press 1 to set datatable to null, press 2 to dispose datatable directly");
string key = Console.ReadLine();
if (key == "0")
{
table.Clear();
table.Dispose();
Console.WriteLine("Datatable disposed, data table row count is {0}", table.Rows.Count);
GC.Collect();
long lMemoryMB = GC.GetTotalMemory(true/* true = Collect garbage before measuring */)/1024/1024; // memory in megabytes
Console.WriteLine(lMemoryMB);
}
else if (key == "1")
{
table = null;
GC.Collect();
long lMemoryMB = GC.GetTotalMemory(true/* true = Collect garbage before measuring */)/1024/1024; // memory in megabytes
Console.WriteLine(lMemoryMB);
}
else if (key == "2")
{
table.Dispose();
GC.Collect();
long lMemoryMB = GC.GetTotalMemory(true/* true = Collect garbage before measuring */)/1024/1024; // memory in megabytes
Console.WriteLine(lMemoryMB);
}
Console.WriteLine("Job finish, please check memory");
Console.WriteLine("Press 0 to exit, press 1 to load more data and check if throw out of memory exception");
key = Console.ReadLine();
if (key == "0")
{
Environment.Exit(0);
}
else if (key == "1")
{
LoadData();
}
}
}
}
'сама DataTable' не реализует' Dispose() ', он получает метод от его родителя' MarshalByValueComponent' и только две вещи, 'MarshalByValueComponent' делает вызов' сайта .Container.Remove (this) ', если у вас есть таблица данных внутри [' ISite'] (https://msdn.microsoft.com/en-us/library/system.data.datatable.site (v = vs. 110) .aspx) (что вы не делаете в своем примере кода) и поднимите ['Disposed'] (https://msdn.microsoft.com/en-us/library/system.componentmodel.marshalbyvaluecomponent.disposed (v = vs.110) .aspx). Он не выделяет никаких ресурсов. –
Я не знаю, но я уверен, вы получаете свои объекты, но у вас проблемы с фрагментацией памяти. EDIT: OH, запустите свою программу без отладчика, подключенного в режиме деблокирования, вы увидите другое поведение. ГК ведет себя очень сильно, когда подключен отладчик. –
@ScottChamberlain Спасибо. Но в моем случае эта загрузка данных находится внутри каталога, смотрящего exe. Чтобы предотвратить исключение OutOfMemoery, что мне делать? – mhan0125