Неожиданное исключение OutOfMemory в ILNumerics
Следующий код VB .net дает мне исключение нехватки памяти. Кто-нибудь знает почему?
Dim vArray As ILArray(Of Double) = ILMath.rand(10000000)
Using ILScope.Enter(vArray)
For i As Integer = 1 To 100
vArray = ILMath.add(vArray, vArray)
Next
End Using
Большое спасибо.
1 ответ
В этом примере с игрушкой вы можете просто удалить искусственный прицел, и он будет работать нормально:
Dim vArray As ILArray(Of Double) = ILMath.rand(10000000)
For i As Integer = 1 To 100
vArray = ILMath.add(vArray, vArray)
Next
Console.WriteLine("OK: " + vArray(0).ToString())
Console.ReadKey()
Однако в более серьезной ситуации ILScope станет вашим другом. Как указано на странице ILNumerics, искусственная область действия обеспечивает детерминированное управление памятью:
Все массивы, созданные внутри области видимости, удаляются после того, как блок был оставлен.
В противном случае нужно было полагаться на GC для очистки. И, как вы знаете, это включает в себя коллекцию второго поколения для крупных объектов - со всеми недостатками с точки зрения производительности.
Чтобы иметь возможность распоряжаться массивами, их нужно как-то собирать и отслеживать. Подходит ли это для термина "утечка памяти" - это скорее философский вопрос. Я не буду вдаваться в это здесь. Дело в том, что после того, как указатель инструкций выйдет из области видимости, об этих массивах позаботятся: их память будет помещена в пул памяти и будет использоваться повторно. Как следствие, никакой GC не будет запущен.
Схема особенно полезна для длительных операций и для больших данных. В настоящее время массивы освобождаются только ПОСЛЕ того, как был оставлен блок области видимости. Так что, если вы создаете алгоритм / цикл, который требует больше памяти, чем доступно на вашем компьютере, вам нужно очистить уже во время цикла:
Dim vArray As ILArray(Of Double) = ILMath.rand(10000000)
For i As Integer = 1 To 100
Using ILScope.Enter
vArray.a = ILMath.add(vArray, vArray)
' ...
End Using
Next
Здесь область очищает память после каждой итерации цикла. Это влияет на все локальные массивы, назначенные в теле цикла. Если мы хотим, чтобы значение массива переживало итерацию цикла, мы можем присвоить его .a
свойство, как показано с vArray.a
,