1

The following VB .net code gives me an out of memory exception. Does anybody knows why?

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

Thank you very much.

Haymo Kutschbach
  • 3,322
  • 1
  • 17
  • 25
  • 4
    "Memory leaks" and "out of memory exceptions" are very different things. – bzlm Jul 22 '15 at 20:33
  • 1
    How about without the `Using ILScope.Enter(vArray)`? Does that keep all of the arrays in memory until the `End Using`? – Mark Jul 22 '15 at 20:36
  • rand(10000000) tries to create a matrix with 10^14 elements. Don't know if this is intended but it will hardly work out, no? – Haymo Kutschbach Jul 22 '15 at 22:13
  • Thanks a lot for the answers. Removing `Using ILScope.Enter(vArray)` does not help. `ILMath.rand(10000000)` creates a vector with 10^7 which easily fits into memory. From debugging I know that the first allocation works. Also the first 10 iterations are done without problems. Only in the 11th iteration I get the out of memory exception. Hence, the code seem to allocate memory in each iteration without freeing old memory. To my understanding this is called memory leak. – Ralf Hielscher Jul 23 '15 at 20:51

1 Answers1

0

In this toy example you can simply remove the artificial scope and it will run fine:

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()

However, in a more serious situation, ILScope will be your friend. As stated on the ILNumerics page an artificial scope ensures a deterministic memory management:

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

Otherwise one had to rely on the GC for cleanup. And, as you know, this involves a gen 2 collection for large objects – with all disadvantages in terms of performance.

In order to be able to dispose the arrays they need to be collected and tracked somehow. Whether or not this qualifies for the term 'memory leak' is rather a philosophical question. I will not go into it here. The deal is: after the instruction pointer runs out of the scope these arrays are taken care of: their memory is put into the memory pool and will be reused. As a consequence, no GC will be triggered.

The scheme is especially useful for long running operations and for large data. Currently, the arrays are released only AFTER the scope block was left. So if you create an algorithm/ loop which requires more memory than available on your machine you need to clean up DURING the loop already:

    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

Here, the scope cleans up the memory after each iteration of the loop. This affects all local arrays assigned within the loop body. If we want an array value to survive the loop iteration we can assign to its .a property as shown with vArray.a.

Haymo Kutschbach
  • 3,322
  • 1
  • 17
  • 25