You are not logged in.
I suspect this is related to the new automatic RTTI initialization of records for serialization.
Using the 'Project14ServerHttp' demo, the following declaration in the interface will cause a memory leak:
/// some common definitions shared by both client and server side
unit Project14Interface;
interface
type
TTestRec = packed record
Value1: Integer;
Value2: Integer;
end;
ICalculator = interface(IInvokable)
['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}']
function Add(n1,n2: integer): integer;
function GetTestRec(Id: integer; out aRec: TTestRec): Boolean; <-----------------------
end;
const
ROOT_NAME = 'root';
PORT_NAME = '888';
APPLICATION_NAME = 'RestService';
implementation
end.
/// this server will use TSQLRestServerFullMemory over HTTP
program Project14ServerHttp;
{$APPTYPE CONSOLE}
uses
FastMM4,
SysUtils,
Classes,
SynCommons,
mORMot,
mORMotHttpServer,
Project14Interface;
type
TServiceCalculator = class(TInterfacedObjectWithCustomCreate, ICalculator)
public
function Add(n1,n2: integer): integer;
function GetTestRec(Id: integer; out aRec: TTestRec): Boolean;
end;
function TServiceCalculator.Add(n1, n2: integer): integer;
begin
result := n1+n2;
end;
function TServiceCalculator.GetTestRec(Id: integer; out aRec: TTestRec): Boolean;
begin
aRec.Value1 := 1;
aRec.Value2 := 2;
Result := True;
end;
[...]
begin
ReportMemoryLeaksOnShutdown := True; <-----------------------
[...]
end.
You just need to run it, and then press the Enter key.
Offline
We have just fixed several memory leaks under newer versions of Delphi.
Main issue was linked to enhanced RTTI, as you discovered.
And there was also some problems due to newer compiler issues, like unproper method inlining or old object type regression.
Now all regression tests pass, without any memory leak reported.
See http://synopse.info/fossil/info/2ccd2e0b6f
Thanks a lot for the feedback, and to have supplied a simple program to reproduce the issue.
It is so much easier to investigate when you got something to work clear on!
Offline
Glad my example helped.
I've encountered another case, where the memory manager reports a leak.
If you reference a threadvar in the code, before raising an exception, a leak occurs:
threadvar <---------------------------------
aString: string; <---------------------------------
function TServiceCalculator.Add(n1, n2: integer): integer;
begin
result := n1+n2;
end;
function TServiceCalculator.GetTestRec(Id: integer; out aRec: TTestRec): Boolean;
begin
aRec.Value1 := 1;
aRec.Value2 := 2;
aRec.Value3 := 'test';
aString := 'test'; <---------------------------------
raise Exception.Create('Error Message');
Result := True;
end;
It's an unusual case, but we encountered it because one of our threads did something similar.
Last edited by avista (2014-06-22 20:19:22)
Offline
This is not linked to mORMot, but to threadvar itself.
You should not use a managed type within a threadvar, otherwise a memory leak may occur.
See http://www.delphibasics.co.uk/RTL.asp?Name=ThreadVar
and http://stackoverflow.com/q/5456317/458259
My advice is to never use a string in a threadvar, but non managed values (like integer/cardinal) or pointers/objects to some data which will have their live time managed by other piece of code.
Offline
Thanks, we will change the code to avoid this.
Offline