#1 2014-07-06 14:53:44

syagrius
Member
Registered: 2013-02-27
Posts: 13

Possible memory leak with RecordLoadJSON using enhanced RTTI

Hi there!

I'm new to this forum.
And mOMRot is the first animal I try to tame.

I read SAD and took a look at “25 - JSON Performance” sample.

I try to unmarshalling a JSON string using RecordLoadJSON.

The JSON looks like this:

{	
	"name": "Book the First",
	"author": {
		"first_name": "Bob",
		"last_name": "White"
	}
}

I use Delphi 2010 so mORMot will automatically use enhanced RTTI information (using a TJSONCustomParserFromRTTI automatically).

This is great and everything is OK.
But FastMM4 report a memory leak.

My code to reproduce:

type
  TBookRecord = packed record
    name: string;
    author: record
      first_name:string;
      last_name:string;
    end;
  end;
var
  B:  TBookRecord;
  Json:  RawUTF8;
begin
  ReportMemoryLeaksOnShutdown:=true;
  Json :='{ "name": "Book the First", "author": { "first_name": "Bob", "last_name": "White" } }';
  RecordLoadJSON(B,@Json[1],TypeInfo(TBookRecord));
end;

Maybe I'm wrong or I forget to release something.
But I think an instance of TJSONCustomParserFromRTTI is not released.

For instance in SynCommons.pas, in function TJSONCustomParsers.TryToGetFromRTTI()

Reg.RecordCustomParser := TJSONCustomParserFromRTTI.Create(Reg.RecordTypeInfo,RegRoot);

Did I miss anything?

Offline

#2 2014-07-06 16:40:56

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: Possible memory leak with RecordLoadJSON using enhanced RTTI

ReportMemoryLeaksOnShutdown should be set sooner in the .DPR file I suppose.

We tried to reproduce your issue, and no memory leak was reported here.
See http://synopse.info/fossil/info/886b68519349eee1e

Offline

#3 2014-07-06 17:52:33

syagrius
Member
Registered: 2013-02-27
Posts: 13

Re: Possible memory leak with RecordLoadJSON using enhanced RTTI

Thank you very much for the speed and clarity of your reply.
I updated my mORMot (also thank you about the ingenious idea of using git now).

I noticed that TestSQL3 is working without any memory leak.

But I still have a leak after moving ReportMemoryLeaksOnShutdown sooner.
I also tried Eurekalog with the same report.

There is probably something wrong in my code.
I will conduct an extensive search about my project.

Offline

#4 2014-07-06 18:09:28

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: Possible memory leak with RecordLoadJSON using enhanced RTTI

Your code sounds correct.
Perhaps there is something wrong with the framework by we were not able to reproduce it.

Offline

#5 2014-07-06 18:51:54

syagrius
Member
Registered: 2013-02-27
Posts: 13

Re: Possible memory leak with RecordLoadJSON using enhanced RTTI

I think your can reproduce my issue.

1 - open TestSQL3.dpr
2 - comment the call to SQLite3ConsoleTests()
3 - and add my code snippet
For instance

  // SQLite3ConsoleTests;
  Json :='{ "name": "Book the First", "author": { "first_name": "Bob", "last_name": "White" } }';
  RecordLoadJSON(B,@Json[1],TypeInfo(TBookRecord));

4 - Run, You got a memory leak
5 - Reactivate the call to SQLite3ConsoleTests()
6 - Run, No memory leak!

I have been noticing another thing.
I have no leak after a simple call to RecordSaveJSON(), but only if TypeInfo points to a record without nested record

  // SQLite3ConsoleTests;   
  RecordSaveJSON(g,TypeInfo(TGUID)); // Calling RecordSaveJSON() *BEFORE* RecordLoadJSON() will remove the leak
  Json :='{ "name": "Book the First", "author": { "first_name": "Bob", "last_name": "White" } }';
  RecordLoadJSON(B,@Json[1],TypeInfo(TBookRecord));

The code above is working.



  // SQLite3ConsoleTests;   
  RecordSaveJSON(B,TypeInfo(TRecordWithNestedRecord)); // No effect
  Json :='{ "name": "Book the First", "author": { "first_name": "Bob", "last_name": "White" } }';
  RecordLoadJSON(B,@Json[1],TypeInfo(TBookRecord));

Memory leak still remain.

Last edited by syagrius (2014-07-07 07:20:05)

Offline

#6 2014-07-07 12:42:51

syagrius
Member
Registered: 2013-02-27
Posts: 13

Re: Possible memory leak with RecordLoadJSON using enhanced RTTI

I wrote a simple DPR to reproduce the memory report.
Tested under different computers with same result.

jsonleak.dpr

program jsonleak;

{$APPTYPE CONSOLE}

uses
  FastMM4,
  SynCommons;

type
  TBookRecord = packed record
    Name: string;
    author: record
      first_name:string;
      last_name:string;
    end;
  end;

var
  Json:  RawUTF8;
  B:  TBookRecord;

begin
  ReportMemoryLeaksOnShutdown:=True;

  Json :='{ "name": "How to tame a mormot", "author": { "first_name": "Bob", "last_name": "White" } }';
  RecordLoadJSON(B,@Json[1],TypeInfo(TBookRecord));
end.

Offline

#7 2014-07-07 13:15:08

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: Possible memory leak with RecordLoadJSON using enhanced RTTI

It should be fixed now.
See http://synopse.info/fossil/info/187058910fc95b0b

Thanks for the report, and investigation.
Sorry for the delay.

Offline

#8 2014-07-07 13:35:46

syagrius
Member
Registered: 2013-02-27
Posts: 13

Re: Possible memory leak with RecordLoadJSON using enhanced RTTI

Everything is working now.
About the delay it was perfect.

Thank you!

Last edited by syagrius (2014-08-03 13:35:47)

Offline

Board footer

Powered by FluxBB