Delphi XE8:方法 datasnap 服务器内存泄漏

Delphi XE8 : Memory Leak with method datasnap server

我目前正在使用 Delphi 设计 Datasnap 休息服务器。但是我有严重的内存泄漏。

比如我的方法station

procedure TV1.station(ID: integer);
begin


  GetInvocationMetadata().ResponseContent := Manager.xxxxxxAPI.GetObjectStation(ID);
  GetInvocationMetadata().CloseSession := true;     

end;

哪个调用这个函数:

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;

您可以看到,我使用 resultContent 而不是函数的结果,因为我不想在 json 响应中使用 result:

因此根据 ReportMemoryLeaksOnShutdown 的报告,我看到我所有的 json 对象和每个 json 对都没有被破坏!!!

Result leak memory report, 5501 request from my client application

来自服务器的生命周期class:会话

我使用 DSRESTWebDispatcher,在 Session Cycle 和 Timout 中设置为 60000。

有人解释一下吗?我忘记做某事了吗?

您应该调用 jsonObject.Free 而不是 jsonObject.FreeInstance

永远不要直接调用 FreeInstance 来释放对象。它是内部 allocation/deallocation 机制的一部分。在 Delphi 中,析构函数会自动调用 FreeInstance 来释放对象实例内存。

在 Delphi 中释放对象实例的正确方法是:

  1. TObject.Free - 如果实例不是 nil

  2. ,则调用对象实例析构函数
  3. TObject.DisposeOf - 在 Delphi ARC 移动编译器中引入,在桌面编译器上它调用 TObject.Free.

  4. FreeAndNil(var Obj) - 在传递的对象实例上调用 Free 的过程和引用

  5. 的 nils