ILNumerics 中的意外 OutOfMemoryException

Unexpected OutOfMemoryException in 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

非常感谢。

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

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 中所述,人工作用域可确保确定性内存管理:

All arrays created inside the scope are disposed once the block was left.

否则就得靠GC来清理了。而且,如您所知,这涉及大型对象的第 2 代集合——在性能方面存在所有缺点。

为了能够处理阵列,需要以某种方式收集和跟踪它们。这是否符合术语 'memory leak' 是一个哲学问题。我不会在这里深入。交易是:在指令指针 运行s 超出范围后,这些数组将得到处理:它们的内存被放入内存池并将被重用。因此,不会触发 GC。

该方案对于长 运行ning 操作和大数据特别有用。目前,仅在离开范围块后才释放数组。因此,如果您创建的算法/循环需要的内存多于您机器上可用的内存,则您需要在循环期间进行清理:

    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 所示。