Die konkrete Antwort ist wahrscheinlich folgende Zeile:
TmpPair.JsonValue := ...
Die Implementation von TJsonPair.SetJsonValue(..) sieht nur so aus:
Delphi-Quellcode:
procedure TJSONPair.SetJsonValue(const Val: TJSONValue);
begin
if Val <> nil then
FJsonValue := Val;
end;
Heißt: Er biegt einfach nur seine Referenz FJsonValue um. Richtig wäre wahrscheinlich erst zu schauen ob das bisherige FJsonValue.GetOwned() = True hat und dieses dann erst einmal freizugeben. Das tut er nicht, und das alte JsonValue verbleibt als Speicherleck. Zumindest in meinem Delphi 10.0 Seattle.