Windows Memory Usage

I have a Windows desktop app (using Xojo v2025r3) and I wanted to monitor the memory usage to ensure no leaks etc as the app is in use continuously for around 18 hours per day, 7 days a week in multiple sites.

I asked my new best friend (ChatGPT) for some code and it came up with the method below. This data is written to a log file every hour or so and I have a dashboard (using Klipfolio) to display each site and the current memory usage. All sounding great so far!

However, as each site uses the exact same app, it’s very odd to see the memory vary from less than 100Mb in one site to over 500Mb on another. It doesn’t even tally with how long the app has been running (so the longer it’s running doesn’t tally necessarily with the amount of ram being used).

I assume memory will go up and down to a degree during usage / database access etc. etc. but does this variation sound realistic? I’m wondering if the usage code is actually accurate at all, although it could just be Windows memory management in-efficiences? I’m not familiar with Windows calls but it looks logical to the naked eye. Has anyone else managed to acheive something similar and get sensible results? Any thoughts appreciated.

Public Function GetMemoryUsedBytes() As UInt64
  #If TargetWindows And Target64Bit Then
    //Declare Function GetCurrentProcess Lib "kernel32" () As Ptr
    Declare Function GetProcessMemoryInfo Lib "psapi" (hProcess As Ptr, ByRef counters As PROCESS_MEMORY_COUNTERS, ByVal size As UInt32) As Boolean
    
    Var h As Ptr = GetCurrentProcessHandle()
    Var mem As PROCESS_MEMORY_COUNTERS
    mem.cb = CType(mem.Size, UInt32)
    If GetProcessMemoryInfo(h, mem, mem.cb) Then
      Return mem.WorkingSetSize
    Else
      Return 0
    End If
  #Else
    Return 0
  #EndIf
End Function

I can recommend xojoinstruments to find possible memory leaks

Thanks, I’ll look into that :+1:

I log Runtime.MemoryUsed & Runtime.ObjectCount to get insights into what’s happening in my apps.

2 Likes

When you want to detect memory leaks, WorkingSetSize is not the correct metric.

Microsoft: Working Set

The Working Set of a Process is the set of pages in the virtual address space of the current process that are currently resident in physical memory.

This will not only depend on your process, but also (among others) on total available physical memory, and on what else is running on the system, and how the system is configured.

You should probably use PageFileUsage (which is named misleadingly and is equal to PrivatUsage if you extent the struct and use PROCESS_MEMORY_COUNTERS_EX instead).

But I think, Wayne Golding’s suggestion will work just as well.

On windows, it’s also good to check you aren’t leaking Handles: