以下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
非常感谢。
答案 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
所示。