Ich würd zunächst in die
DPR an den Anfang
ReportMemoryLeaksOnShutdown := True
schreiben und dann mal die Anwendung mal manuell beenden, bevor die
Exception kommt. Dann siehst du (wahrscheinlich) zumindest schon mal, was da eigentlich den Speicher zumüllt. Wo der Cursor stehen bleibt, ist nämlich wenig aussagekräftig, denn das zeigt dir ja nur, wo der Tropfen das Fass zum Überlaufen gebracht hat.
Ansonsten seh ich da jetzt auf den ersten Blick nichts. Ich denke, da ist mehr Code erforderlich, um eine Diagnose zu stellen... z.B. seh ich nirgendwo den Timer, von dem du redest.
Was noch sein könnte, ist, dass innerhalb des Threads eine stille
Exception auftritt, wodurch eine Routine frühzeitig abgebrochen wird, bevor ein Objekt freigegeben wird. In solchen Fällen ist Try-Finally wirklich wichtig. Du kannst ja mal einen Breakpoint in den Thread setzen um dir die Exceptions anzeigen zu lassen.