Тема: Великі одновимірні масиви і OutOfMemoryException
В мене виникла проблема при створенні великого одновимірного масиву-буферу. Його розмір мав бути кілька гігабайт. Як пише книжка, в .Net память під одновимірні масиви виділяється послідовно, одним шматком. Такого великої ділянки вільної памяті система не знайшла і я отримав OutOfMemoryException під час виконання.
Виникла ідея шукати найбільшу доступну ділянку памяті і формувати масив відповідного розміру. Точна кількість елементів в масиві значення не має, її можна зменшувати, якщо масив не влазить в память. Методів для визначення розмірів вільних ділянок памяті я не знайшов, тому вирішив сам щось придумати.
Створив клас з методом, куди передається тип масиву і бажаний розмір (_requiredSizeOfArray). Клас пробує створити масив заданого розміру, якщо не виходить, то OutOfMemoryException подавляється і бажаний розмір зменшується на заданий відсоток (_percentOfDecrease). Спроба повторюється знову, доки масив не буде створено.
Якщо вільної памяті взагалі немає, то повернеться масив нульвого розміру
Чи знає хто кращий варіант для цієї проблеми ? якщо ні то може моя ідея ще кому стане в нагоді.
public class LargeMemoryHelper
{
public static T[] GetArrayInAvailableMemory<T>(ref int _requiredSizeOfArray, ushort _percentOfDecrease=10)
{
T[] _retArray = new T[] { };
if (_percentOfDecrease > 99) throw new Exception(
"LargeMemoryHelper.GetArrayInAvailableMemory<>(): Percent of decrease should be less 100");
try
{
double _sizeArray=_requiredSizeOfArray;
while (_retArray.Length == 0)
{
_retArray = TryToCreateArray<T>(_requiredSizeOfArray);
if (_retArray.Length == 0)
{
_sizeArray = _sizeArray * (1 - (double)_percentOfDecrease / 100);
_requiredSizeOfArray = (int)Math.Truncate(_sizeArray);
}
if (_requiredSizeOfArray == 0)
break;
}
}
catch(Exception _ex)
{
SysLog.SaveToLog("LargeMemoryHelper. Type:" + typeof(T).ToString() +
" Required size of array "+ _requiredSizeOfArray.ToString() + "\r\n" + _ex.Message);
}
return _retArray;
}
private static T[] TryToCreateArray<T>(int _sizeOfArray)
{
T[] _retArray = new T[] { };
try
{
_retArray = new T[_sizeOfArray];
}
catch (OutOfMemoryException) { }
return _retArray;
}
}
SysLog.SaveToLog() це логування при якихось інших непередбачених проблемах. Можете там юзати що вам самим треба.