Min/Max Functions Cause Double() Memory Leak When Used In Loops

I think I found the cause of a huge memory leak I was having in one of my apps.

I was rendering graphs from some data I had and was using code like what is found below:

For i As Integer = 0 to Min(Width/BAR_WIDTH,Data.Ubound)
...
End For

I was having quite a horrible memory leak in my webapp (4+gb in less than a few days) and tracked it down to 10’s of 1000’s of empty Double() arrays each with 2-3 references. I had no idea where these were coming from as nowhere in the app do I create empty Double() arrays. When I get the count once first and store it in a variable then use that to loop through, there is no leak. I just wanted to not loop past the data if it were to change while rendering. This also appears to be happing for Max as well.

Dim n As Integer = Min(Width/BAR_WIDTH,Data.Ubound)
For i As Integer = 0 to n
...
End For

Has anyone found that they are having this issue or know of a bug report for it? If not, I will post a bug report.

What version of xojo are you using?

Xojo 2019 R1.1

Do you alter Data inside the For?

I access it but do not modify it.

Interesting, not sure then, a simple project with it happening would be useful, maybe pop a ticket in with the project attached as you mentioned above, I certainly can’t think what could be causing it at this hour of the morning :slight_smile:

Yeah, just a button with the code mentioned is enough to cause the leak, happens in both Web and Desktop.

I assume it has something to do with ParamArray taking in a blank array of doubles, but not getting destroyed by the ARC GC.

I’d want to see actual code for this
I’m sure there’ lots of code that uses loops doubles and min max and I dont see anyone else reporting this as an issue

The code mentioned doesn’t work and I don’t really want to guess your variable types as that might be part of the issue :slight_smile:

new desktop app
add push button to the window
in ots action event put

System.DebugLog Str(Runtime.MemoryUsed)

For i As Integer = 1 To 1000
  Untitled(1,0,2,2)
Next

System.DebugLog Str(Runtime.MemoryUsed)

add a method

Private Sub Untitled(ParamArray data as double)
  // Dim width As Double
  // Const bar_width = 123
  // 
  // For i As Integer = 0 To Min(Width/BAR_WIDTH,Data.Ubound)
  // 
  // Next
  
  
End Sub

run a few times and push the button :stuck_out_tongue:
seems to have nothing to do with min max etc just a paramarray

fun find
that would explain why this is not seen in other code I’m familiar with
it doesnt use paramarrays

lest you think “Oh no problem I’ll ditch the paramarray and use one I allocated”
swap the button code for this

System.DebugLog Str(Runtime.MemoryUsed)

Dim d() As Double = Array(1.0,0.0,2.0,2.0)
For i As Integer = 1 To 1000
  Untitled(d)
Next

System.DebugLog Str(Runtime.MemoryUsed)

and alter the method to

Private Sub Untitled(data() as double)
  
End Sub

run a few times again

Interesting…

for i as integer = 0 to min(1,1)

Creates 1 double()

for i as integer = 0 to min(100,100)

Creates 100 double()

Sample Project, changing the numbers in the Min(1,1) to something else will create that many Double() arrays.

https://static.craftymynes.com/LeakTest.xojo_binary_project

the ENDING loop condition is evaluated EVERY TIME through the loop
so with min(100,100) it evaluates min(100,100) each time which creates a new object
the first doesnt because N is computed ONCE
use the first form and you’re fine
you can see it if instead of MIN you do this in pushbutton1

[code]
Dim n As Integer = foo(100,100)

for i as integer = 0 to n

next

CountDoubles[/code]
and this in pushbutton2

For i As Integer = 0 To foo(100,100)
  
next

CountDoubles

and defined foo as

Public Function foo(d1 as double, d2 as double) as double
   System.debuglog currentmethodname
  return min(d1,d2)
End Function

FWIW this is expected and has been long standing behaviour
Dont expect it to be changed

Old bug I’m afraid, nice to see Xojo on the ball… 2015 :frowning:

<https://xojo.com/issue/40114>

and dead easy to work around

precompute the loop bounds

[quote=449203:@Norman Palardy]and dead easy to work around

precompute the loop bounds[/quote]

Yeah, I figured that out, just wanted to share for anyone else who might have the same issue.

[quote=449202:@JulianS]Old bug I’m afraid, nice to see Xojo on the ball… 2015 :frowning:

<https://xojo.com/issue/40114>[/quote]

Voted!

It boggles my mind that something like that would be knowingly left in for 4+ years.