Memory leak scanner

Mharr

Wanted Pirate
I wrote this AutoHotkey script back before the major update when the client was springing memory leaks all over and crashing during single solo voyages, to let me know when it was time to port and relog. Given that crewing seems to have some of the same problems atm, and is important for collecting upgrade materials, I thought it might be useful.

Compiled version here.

Updated to use Brioso Pro Regular piratey font. (Optional)
Updated to react to changes in screen resolution.

Change top and right to adjust the position of the memory display in screen percentages.

Code:
#Singleinstance, Force

top := 23
right := 0

varSetCapacity(spaces,64,asc(" "))

Gui +E0x20 +LastFound +AlwaysOnTop +ToolWindow -Caption -Border
Gui, Color, 000000
WinSet, TransColor, 000000
Gui, Margin, 0, 0
Gui, Font, S16 CFFFFFF, Brioso Pro Regular
Gui, Add, Text, C00FF00 BackgroundTrans vT1, %spaces%
Gui, Add, Text, CFFFF00 BackgroundTrans xp yp vT2, %spaces%
Gui, Add, Text, CFF0000 BackgroundTrans xp yp vT3, %spaces%

SetTimer, Update, 4000
Update:
POs_x := A_Screenwidth * (100 - right) / 100 - 80
pos_y := A_Screenheight * top / 100

Gui, Show, x%pos_x% y%pos_y%

memory := GetProcessMemory_Private("tlopo.exe", "M")
if (memory > 0 && memory < 1200)
  {
  GuiControl,, T1, %memory% MB
  GuiControl,, T2, %spaces%
  GuiControl,, T3, %spaces%
  }
if (memory >= 1200 && memory < 1600)
  {
  GuiControl,, T1, %spaces%
  GuiControl,, T2, %memory% MB
  GuiControl,, T3, %spaces%
  }
if (memory >= 1600)
  {
  GuiControl,, T1, %spaces%
  GuiControl,, T2, %spaces%
  GuiControl,, T3, %memory% MB
  }
Return

;=============================================================================================================
; Func: GetProcessMemory_Private
; Get the number of private bytes used by a specified process.  Result is in K by default, but can also be in
; bytes or MB.
;
; Params:
;   ProcName    - Name of Process (e.g. Firefox.exe)
;   Units       - Optional Unit of Measure B | K | M.  Defaults to K (Kilobytes)
;
; Returns:
;   Private bytes used by the process
;-------------------------------------------------------------------------------------------------------------
GetProcessMemory_Private(ProcName, Units="K") {
    Process, Exist, %ProcName%
    pid := Errorlevel

    ; get process handle
    hProcess := DllCall( "OpenProcess", UInt, 0x10|0x400, Int, false, UInt, pid )

    ; get memory info
    PROCESS_MEMORY_COUNTERS_EX := VarSetCapacity(memCounters, 44, 0)
    DllCall( "psapi.dll\GetProcessMemoryInfo", UInt, hProcess, UInt, &memCounters, UInt, PROCESS_MEMORY_COUNTERS_EX )
    DllCall( "CloseHandle", UInt, hProcess )

    SetFormat, Float, 0.0 ; round up K

    PrivateBytes := NumGet(memCounters, 40, "UInt")
    if (Units == "B")
        return PrivateBytes
    if (Units == "K")
        Return PrivateBytes / 1024
    if (Units == "M")
        Return PrivateBytes / 1024 / 1024
}


;=============================================================================================================
; Func: GetProcessMemory_All
; Get all Process Memory Usage Counters.  Mimics what's shown in Task Manager.
;
; Params:
;   ProcName    - Name of Process (e.g. Firefox.exe)
;
; Returns:
;   String with all values in KB as one big string.  Use a Regular Expression to parse out the value you want.
;-------------------------------------------------------------------------------------------------------------
GetProcessMemory_All(ProcName) {
    Process, Exist, %ProcName%
    pid := Errorlevel

    ; get process handle
    hProcess := DllCall( "OpenProcess", UInt, 0x10|0x400, Int, false, UInt, pid )

    ; get memory info
    PROCESS_MEMORY_COUNTERS_EX := VarSetCapacity(memCounters, 44, 0)
    DllCall( "psapi.dll\GetProcessMemoryInfo", UInt, hProcess, UInt, &memCounters, UInt, PROCESS_MEMORY_COUNTERS_EX )
    DllCall( "CloseHandle", UInt, hProcess )

    list := "cb,PageFaultCount,PeakWorkingSetSize,WorkingSetSize,QuotaPeakPagedPoolUsage"
          . ",QuotaPagedPoolUsage,QuotaPeakNonPagedPoolUsage,QuotaNonPagedPoolUsage"
          . ",PagefileUsage,PeakPagefileUsage,PrivateUsage"

    n := 0
    Loop, Parse, list, `,
    {
        n += 4
        SetFormat, Float, 0.0 ; round up K
        this := A_Loopfield
        this := NumGet( memCounters, (A_Index = 1 ? 0 : n-4), "UInt") / 1024

        ; omit cb
        If A_Index != 1
            info .= A_Loopfield . ": " . this . " K" . ( A_Loopfield != "" ? "`n" : "" )
    }

    Return "[" . pid . "] " . pname . "`n`n" . info ; for everything
}

Memory usage functions courtesy of Wade Hatler.
 
Last edited:
So it just checks memory usage for tlopo.exe?
The game crashes at nearing 2gb of ram usage currently, and the game doesn't garbage collect very efficiently given that very small amount of ram it can use. So this script basically tells you if you should relog to avoid a crash, effectively manually doing a garbage collect. Without having to have open task manager or something similar.
 
Last edited:
Yep. If you have a second monitor you can do the same job by just keeping the task manager open on it, this thing is just easier to read. It displays a transparent memory readout for tlopo.exe on the top right of the screen (Position can be adjusted using the variables top and right) in green, yellow and red as it approaches 2G. When TLOPO crashes, the last reading will remain on screen until you relaunch the game or kill the script.
 
Do I just run the executable? Instructions?
For security and flexibility, and because it's awesome, I'd recommend installing AutoHotkey yourself and downloading the actual .ahk script, but the .exe should be identical. (Give it a virus scan though, I'm clean AFAIK but trust no-one!) It'll run without downloading the linked font, but it matches the look of the game better if you do.

It doesn't have any settings or arguments, it just waits for tlopo.exe to open a window, then starts displaying memory usage for that process.
 
For security and flexibility, and because it's awesome, I'd recommend installing AutoHotkey yourself and downloading the actual .ahk script, but the .exe should be identical. (Give it a virus scan though, I'm clean AFAIK but trust no-one!) It'll run without downloading the linked font, but it matches the look of the game better if you do.
I still have no clue what to do.
 
Honestly, if you're not comfortable with random .exe files that don't make their own install folders and shortcut icons I wouldn't mess with it. Just use the task manager to watch memory usage. (CTRL SHIFT ESCAPE)
 
Honestly, if you're not comfortable with random .exe files that don't make their own install folders and shortcut icons I wouldn't mess with it. Just use the task manager to watch memory usage. (CTRL SHIFT ESCAPE)
The program works except the number shows on my desktop instead of in-game. I just want to know how to make the program work.
 
Ahhh, it might not get on well with full screen mode. Gimme an hour or so, I should be able to fix that. (Depends how full screen works exactly, every game has its own slightly different trick)
 
Careful, this post has the word Auto in it and as you know if you use any kind of automation or third party auto clicker macro software's even for 1 millisecond you'll be banned for 50 years so be careful xddddddd
 
AutoHotkey did start life as a clicker and keyboard input automation tool, but it's been a full programming language for many years now. I mostly use it to precisely reposition and resize games that don't offer a native fullscreen window mode, and to change what the extra mouse buttons do on a per-game basis. It's never triggered VAC or similar for me.

Looks like we're down for an update ATM, which is going to delay me a little. I might have to come back to this in the morning. Meanwhile it does totally work in windowed mode!
 
Last edited:
Im making a joke mainly. Seeing the current state of things that is.



Probably down to fix the PVP Glitch which I found and reported myself.
 
Yeah, that was the setting I use just to be clear.
Okay, I think that's fixed. It was displaying the readout offscreen if you used a game resolution smaller than your desktop.
(I've gotten in the habit of always making them match to avoid crashes caused by alt-tabbing and pop-up messages, also that thing where all your desktop icons get rearranged.)
 
Last edited:
Back
Top