ILNumerics中出现意外的OutOfMemoryException

时间:2015-07-22 20:14:06

标签: vb.net memory-management memory-leaks garbage-collection 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 个答案:

答案 0 :(得分:0)

在这个玩具示例中,您可以简单地删除人工范围,它将运行良好:

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 page所述,人工范围确保了确定性的内存管理:

  

在作用域内创建的所有数组都会在块中处理   左

否则,必须依靠GC进行清理。而且,如您所知,这涉及用于大型对象的第2代集合 - 在性能方面存在所有缺点。

为了能够处理阵列,需要以某种方式收集和跟踪它们。这是否符合“记忆泄漏”这个术语是一个哲学问题。我不会在这里讨论它。这笔交易是:在指令指针用完范围后,这些数组将被处理:它们的内存被放入内存池并将被重用。因此,不会触发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所示。