Help to find Memory Leak in App class

Firstly, big thanks to anyone who can offer some assistance here. This problem is driving me up the wall!

I have a cgi app currently running on Xojo Cloud. It all functions well. (2019r1.1)
In the event I instantiate a Timer which fires a Method at intervals. If the Method is empty - no memory leak occurs. If the Method contains the code (see below), then the App’s memory usage grows continuously until the server falls over. Something in this Method is causing the leak but I just cannot see it.

The Method code is below (It just checks a list of members in a database, and then iterates through active sessions to see if members are still online or not.

This is the entire code of the Method (within the App class)

//Now loop through players to check they are still online
Dim DB1 As SQLiteDatabase
DB1 = dbConnect
If DB1 <> Nil Then
  //Get list of registered players
  Dim psPlayers As SQLitePreparedStatement = SQLitePreparedStatement(DB1.Prepare("SELECT * FROM players WHERE isonline =?"))
  psPlayers.BindType(0, SQLitePreparedStatement.SQLITE_BOOLEAN)
  psPlayers.Bind(0, True)
  Dim rsPlayers As RecordSet
  rsPlayers = psPlayers.SQLSelect
  if rsPlayers <> nil Then
    if rsPlayers.RecordCount >0 then
      Dim IsStillOnline As Boolean
      While not rsPlayers.EOF
        IsStillOnLine = False
        //check player is still online
        Dim vSession As Session
        Dim i As Integer
        for i = 0 to App.SessionCount -1
          vSession = App.SessionAtIndex(i)
          if vSession.CurrentGameID <> "" Then
            if (vSession.CurrentGameID = rsPlayers.Field("gameid").StringValue AND vSession.PlayerNum = rsPlayers.Field("playernum").IntegerValue) Then 
              IsStillOnline =True
            end if
          end if
          vSession = nil
        If IsStillOnline Then
          //leave alone - Player is still Active
          rsPlayers.Field("isonline").BooleanValue = False
        end if
    end if
  end if
end if

can you test it with this change?

Dim psPlayers As SQLitePreparedStatement = SQLitePreparedStatement(DB1.Prepare("SELECT * FROM players WHERE isonline =?"))


Dim psPlayers As SQLitePreparedStatement = DB1.Prepare("SELECT * FROM players WHERE isonline =?")

according to the manual this type cast is not necessary.

Thank you Markus for your good suggestion. I have implemented - but sadly the leak continues.

The only other code which runs with this method is the “dbConnect” routine (again within the App class, is this:

[code]//Dim varPath As String
Dim db As New SQLiteDatabase
Dim dbFile as FolderItem
Dim mode As Integer
// change DB paths if app is running in local test mode
mode = app.Mode

Select Case mode
Case 0
dbFile = GetFolderItem(“snazgame.sqlite”)
Case 1
dbFile = SpecialFolder.SharedDocuments.Child(“snazdata”).Child(“snazgame.sqlite”)
end Select

If dbFile <> nil Then
If dbFile.Exists Then
//The sqlite file is found ok

db.DatabaseFile = dbFile

If db.Connect Then
  //the instance named db is connected ok
  //dbf is encrypted
  db.EncryptionKey = App.DbKey
  if db.Connect then
    // connection successful
    //dbErrorFile = "App DB connecton error!"
    //dbError = True
  End if
End If

//dbErrorFile = “App DB file not found”
//dbError = True
End if
//dbErrorFile = “Invalid path for db”
//dbError = True
end if
If db <> Nil Then
Return db
Return Nil
end if[/code]

you could add this into your app
and instead of a timer use a button to trigger your methods.

Ah, yes - that’s a good idea! Thanks :wink:

This is interesting. So I have disabled the app timer, and now call the offending method with a button.
Each time I call the Method, the runtime MemoryUsed goes up by approx 1.5Mb. But the total Object Count does not increase (it varies a little up/down but does not increase over time.

for a test add if 1=0 then
maybe you find that part where the memory increase

and if this method really do a crash let it run with a 20 ms timer.

Something else to try…

Make DB1 a property on the App class and only initialize it if it is Nil, instead of creating a new instance every time this code runs.

Thanks Greg, I will try that, but in the meantime. . .
I have noticed something odd. Perhaps I’m looking in the wrong method. Now that I have added a button on my startup page which simply calls Runtime.MemoryUsed into a text field, I am seeing the memory increasing by about 1.5Mb every 20-30 secs. This is happening continuously even after I disable all App.Timers and do not call my PlayersStatus Method. I have also disabled ALL Open events codes and Shown events codes - so My Startup Page just displays a greeting but no further user interaction and no calls to DB1, etc… Still the memory keeps growing!

I just created a brand new Web App, with nothing on it, except the “Check Memory” button - and sure enough that app’s memory stays static and does not grow.

So my game app must have something in it that is repeating some action… I’m now gonna search for rogue timers!!

Thank you both Greg & Markus for taking the time to help.

Look specifically for places where you’ve created properties which reference other objects. For instance, if you were to subclass a web control and added a property that stores the page that it’s on. The page has to keep track of its children, but making a hark link in the other direction means that the items can never be truly destroyed.

Cool, thanks guys. If found the leak!! The boat is no longer sinking!

I had a webtimer on a container which called a method at 5sec intervals. That method included a reference to a text field in another container, which itself referred back to the caller! There’s your circular reference. Very many thanks for taking the time to assist me - much appreciated.