You don't by any chance use threads?
Because you have calls to LCL controls on the form. And that is only allowed in the main thread. Just in case.
I don't know what of the below will be useful.
Just a few "tricks" to check mem alloc stuff. Maybe something in those can help...
You can always pull info from the FPC heapmanager
I think (but may need to be double checked)
var h: TFPCHeapStatus;
begin
h := GetFPCHeapStatus;
writeln(h.CurrHeapUsed);
Writeln, or display where ever you need. (there are some more fields)
Then you can see, how much mem is actually used by your app, versus how much is "used" as reserve (or too fragmented to be used).
Then if the actual usage indeed goes up, you can start debugging.
E.g. if in your test memory adds up, but gets released after the loop (which in real life does not happen, if I read you correct?) then you can try a breakpoint in FreeMem.
Only that needs an RTL with debug info. Or you can hook the mem manager, and inject your own. And break in your code (which forwards the call).
var
MMgr: TMemoryManager;
OrigFreemem : Function(p:pointer):ptruint;
OrigFreememSize : Function(p:pointer;Size:ptruint):ptruint;
Function MyFreemem(p:pointer):ptruint;
begin
Result := OrigFreemem(p);
end;
Function MyFreememSize(p:pointer;Size:ptruint):ptruint;
begin
Result := OrigFreememSize(p,Size);
end;
initialization
GetMemoryManager(MMgr);
OrigFreemem := MMgr.Freemem;
OrigFreememSize := MMgr.FreememSize;
MMgr.Freemem := @MyFreemem;
MMgr.FreememSize := @MyFreememSize;
SetMemoryManager(MMgr);
Though you will get a lot of calls. It may not be plausible to check them all.
You can also use that to log calls, depending on where the code is.
E.g. in your main code set a flag "MyVarLogMem := true;" for a small block of the code. Then you can log what happens in there.
Or you can accumulate all allocation sizes
Put a hook an alloc mem: AllocMem : Function(Size:ptruint):Pointer;
Function MyAllocMem (Size:ptruint):Pointer;
begin
result := OrigAllocMem(Size);
if MyVarLogMem then
MyVarMemAllocSum := MyVarMemAllocSum + Size;
end;
Then in your code
MyVarMemAllocSum := 0;
MyVarLogMem := true;
And at the end of the block, print how much was allocated.
Maybe some pattern emerges....
I don't have experience with LazSerial...
What happens if data comes in faster than you process it? Does it have an internal buffer that grows and grows?