Reputation: 105
I'm currently designing a Datasnap rest server with Delphi. But I have serious memory leaks.
For example, my method station
procedure TV1.station(ID: integer);
begin
GetInvocationMetadata().ResponseContent := Manager.xxxxxxAPI.GetObjectStation(ID);
GetInvocationMetadata().CloseSession := true;
end;
Which call this function :
function TSmmAPI.GetObjectStation( const ID: integer ) : string;
(...)
jsonObject := TJSONObject.Create;
stationSelected := xxxxxManager.WorkShops.GetStation( CNCHandle );
with StatesDB.QueryGetCurrentState( stationSelected.Handle ) do begin
if RecordCount <> 0 then begin
ConvertFileToPcom(stationSelected.Ini.FileName, Pcom);
jsonObject.AddPair( TJSONPair.Create('ID', inttostr(ID)));
jsonObject.AddPair( TJSONPair.Create('Name', FieldByName(sbStaStationField).AsString));
jsonObject.AddPair( TJSONPair.Create('Workshop', stationSelected.Shop.Name));
jsonObject.AddPair( TJSONPair.Create('Group', Pcom.Others.GroupName));
jsonObject.AddPair( TJSONPair.Create('CurrentRef', FieldByName(sbStaRefNameField).AsString));
jsonObject.AddPair( TJSONPair.Create('CurrentState', FieldByName(sbStaStateField).AsString));
jsonObject.AddPair( TJSONPair.Create('Job', FieldByName(sbStaOPNameField).AsString));
jsonObject.AddPair( TJSONPair.Create('Order',FieldByName(sbStaOFNameField).AsString));
//(...), I have 12 addpair.
Disconnect;
end;
Destroy;
end;// with StatesDB.QueryGetCurrentState
result := jsonobject.toString;
jsonObject.FreeInstance;
end;
You can see, I use the resultContent instead of result from a function because I don't want result: in my json response.
So with the report from ReportMemoryLeaksOnShutdown, I see that all my jsonObject and each jsonpair are not destroy !!!
Result leak memory report, 5501 request from my client application
LifeCycle from the server class : Session
I use DSRESTWebDispatcher, set in Session Cycle and Timout at 60000.
Someone have an explanation? Did I forget to do something?
Upvotes: 2
Views: 1086
Reputation: 28519
You should call jsonObject.Free
instead of jsonObject.FreeInstance
You should never call FreeInstance
directly to release the object. It is part of internal allocation/deallocation mechanism. In Delphi destructors call FreeInstance
automatically to deallocate object instance memory.
Proper ways to release object instances in Delphi are:
TObject.Free
- calls object instance destructor if instance is not nil
TObject.DisposeOf
- introduced with Delphi ARC mobile compilers and on dektop compilers it calls TObject.Free
.
FreeAndNil(var Obj)
- procedure that calls Free
on passed object instance and nils that reference
Upvotes: 5