#1 2014-10-20 08:57:33

alexdmatveev
Member
Registered: 2014-09-12
Posts: 87

How to avoid memory leak?

Hello,

please show me the way to free memory and avoid exception.

procedure TForm1.Button1Click(Sender: TObject);
var
  transfer, trans: TTransfer;
  tab: TSQLTable;
  objs: TObjectList<TTransfer>;
  i: Integer;
begin
  trans := FMailbox.Headers(mtUnknown);
  tab := trans.FillTable;
  objs := tab.ToObjectList<TTransfer>;

  objs.Free;
  trans.Free; //<--- EXCEPTION IS HERE
end;

////////
function TOmMailbox.HeadersTable(messageFormat: TOmMessageFormat): TSQLTable;
var
  tr: TTransfer;
begin
  if messageFormat = mtUnknown then
    tr := TTransfer.CreateAndFillPrepare(FClient, '')
  else
    tr := TTransfer.CreateAndFillPrepare(FClient, 'messageFormat=?', [Integer(messageFormat)]);
  Result := tr.FillTable;
end;

so I have AV exception. FastMM says me: you try to destroy already freed object.

ok, when I comment the problem line I have memory leak report from FastMM:


--------------------------------2014/10/20 10:52:37--------------------------------
A memory block has been leaked. The size is: 52

This block was allocated by thread 0x36E4, and the stack trace (return addresses) at the time was:
406D06 
4088B7 
408FDE 
4089AC 
69E260 [mORMot.pas][mORMot][mORMot.TSQLRecord.FillPrepare][21505]
69FE0D [mORMot.pas][mORMot][mORMot.TSQLRecord.CreateAndFillPrepare][22103]
7B13FA [OM.Impl.Mailbox.pas][OM.Impl][OM.Impl.Mailbox.TOmMailbox.Headers][68]
7D097D [uMain.pas][uMain][uMain.TForm1.Button1Click][167]
543359 [Vcl.Controls][Vcl][Vcl.Controls.TControl.Click]
565BEF [Vcl.StdCtrls][Vcl][Vcl.StdCtrls.TCustomButton.Click]
5666FD [Vcl.StdCtrls][Vcl][Vcl.StdCtrls.TCustomButton.CNCommand]

The block is currently used for an object of class: TSQLRecordFill

The allocation number is: 6327

Current memory dump of 256 bytes starting at pointer address 7EE6D480:
E8 59 67 00 00 98 F5 7E 01 00 00 00 14 00 00 00 00 00 00 00 B8 09 F3 7E FF FF 07 00 00 00 00 00
00 00 00 00 00 00 00 00 A8 04 09 79 80 80 80 80 80 80 80 80 80 80 80 80 00 00 00 00 41 CA E6 7E
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5A 17 00 00 06 6D 40 00 B7 88 40 00 DE 8F 40 00
67 B5 7A 00 C6 61 7A 00 B2 0A 7D 00 0B CF 60 00 0F CB 60 00 4C 90 40 00 C0 CA 60 00 A1 78 61 00
E4 36 00 00 E4 36 00 00 22 6D 40 00 D5 88 40 00 29 90 40 00 CE 89 40 00 DB 89 40 00 5C 0D 7D 00
87 CF 60 00 5F CD 60 00 88 90 40 00 6F CD 60 00 4E E7 4C 00 34 00 00 00 10 B1 7A 00 B7 A9 C9 86
90 12 94 00 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80
80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 80 48 56 36 79 00 00 00 00 41 C1 E6 7E
è  Y  g  .  .  ˜  õ  ~  .  .  .  .  .  .  .  .  .  .  .  .  ¸  .  ó  ~  ÿ  ÿ  .  .  .  .  .  .
.  .  .  .  .  .  .  .  ¨  .  .  y  €  €  €  €  €  €  €  €  €  €  €  €  .  .  .  .  A  Ê  æ  ~
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  Z  .  .  .  .  m  @  .  ·  ˆ  @  .  Þ    @  .
g  µ  z  .  Æ  a  z  .  ²  .  }  .  .  Ï  `  .  .  Ë  `  .  L    @  .  À  Ê  `  .  ¡  x  a  .
ä  6  .  .  ä  6  .  .  "  m  @  .  Õ  ˆ  @  .  )    @  .  Î  ‰  @  .  Û  ‰  @  .  \  .  }  .
‡  Ï  `  .  _  Í  `  .  ˆ    @  .  o  Í  `  .  N  ç  L  .  4  .  .  .  .  ±  z  .  ·  ©  É  †
  .  ”  .  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €
€  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  €  H  V  6  y  .  .  .  .  A  Á  æ  ~

--------------------------------2014/10/20 10:52:37--------------------------------
A memory block has been leaked. The size is: 532

This block was allocated by thread 0x36E4, and the stack trace (return addresses) at the time was:
41711E [FastMM4.pas][FastMM4][FastMM4.DebugReallocMem][8935]
406D43 
40CEC9 
40D002 
69D2FE [mORMot.pas][mORMot][mORMot.TSQLRecordFill.AddMap][21152]
69D3D8 [mORMot.pas][mORMot][mORMot.TSQLRecordFill.AddMap][21172]
69D6EC [mORMot.pas][mORMot][mORMot.TSQLRecordFill.Map][21260]
40D002 
69B3C6 [mORMot.pas][mORMot][mORMot.TSQLTableJSON.ParseAndConvert][19923]
697C45 [mORMot.pas][mORMot][mORMot.TSQLTable.CreateFromTables][18578]
40904C 

The block is currently used for an object of class: Unknown

The allocation number is: 6329

Current memory dump of 256 bytes starting at pointer address 7EF309B0:
01 00 00 00 28 00 00 00 40 2A FA 7E 00 00 00 00 00 00 00 00 40 2A FA 7E 60 5F E6 7E 01 00 00 00
40 2A FA 7E C0 60 E6 7E 02 00 00 00 40 2A FA 7E 20 62 E6 7E 03 00 00 00 40 2A FA 7E 80 63 E6 7E
04 00 00 00 40 2A FA 7E E0 64 E6 7E 05 00 00 00 40 2A FA 7E 40 66 E6 7E 06 00 00 00 40 2A FA 7E
A0 67 E6 7E 07 00 00 00 40 2A FA 7E 00 69 E6 7E 08 00 00 00 40 2A FA 7E 00 13 E4 7E 09 00 00 00
40 2A FA 7E 60 14 E4 7E 0A 00 00 00 40 2A FA 7E C0 15 E4 7E 0B 00 00 00 40 2A FA 7E 70 16 E4 7E
0C 00 00 00 40 2A FA 7E D0 17 E4 7E 0D 00 00 00 40 2A FA 7E 30 19 E4 7E 0E 00 00 00 40 2A FA 7E
90 1A E4 7E 0F 00 00 00 40 2A FA 7E F0 1B E4 7E 10 00 00 00 40 2A FA 7E 50 1D E4 7E 11 00 00 00
40 2A FA 7E B0 1E E4 7E 12 00 00 00 40 2A FA 7E 10 20 E4 7E 13 00 00 00 00 00 00 00 00 00 00 00
.  .  .  .  (  .  .  .  @  *  ú  ~  .  .  .  .  .  .  .  .  @  *  ú  ~  `  _  æ  ~  .  .  .  .
@  *  ú  ~  À  `  æ  ~  .  .  .  .  @  *  ú  ~     b  æ  ~  .  .  .  .  @  *  ú  ~  €  c  æ  ~
.  .  .  .  @  *  ú  ~  à  d  æ  ~  .  .  .  .  @  *  ú  ~  @  f  æ  ~  .  .  .  .  @  *  ú  ~
   g  æ  ~  .  .  .  .  @  *  ú  ~  .  i  æ  ~  .  .  .  .  @  *  ú  ~  .  .  ä  ~  .  .  .  .
@  *  ú  ~  `  .  ä  ~  .  .  .  .  @  *  ú  ~  À  .  ä  ~  .  .  .  .  @  *  ú  ~  p  .  ä  ~
.  .  .  .  @  *  ú  ~  Ð  .  ä  ~  .  .  .  .  @  *  ú  ~  0  .  ä  ~  .  .  .  .  @  *  ú  ~
  .  ä  ~  .  .  .  .  @  *  ú  ~  ð  .  ä  ~  .  .  .  .  @  *  ú  ~  P  .  ä  ~  .  .  .  .
@  *  ú  ~  °  .  ä  ~  .  .  .  .  @  *  ú  ~  .     ä  ~  .  .  .  .  .  .  .  .  .  .  .  .

--------------------------------2014/10/20 10:52:37--------------------------------
A memory block has been leaked. The size is: 116

This block was allocated by thread 0x36E4, and the stack trace (return addresses) at the time was:
406D06 
4088B7 
408FDE 
69FDD3 [mORMot.pas][mORMot][mORMot.TSQLRecord.CreateAndFillPrepare][22097]
76D76170 [ScriptTextOut]
7B13FA [OM.Impl.Mailbox.pas][OM.Impl][OM.Impl.Mailbox.TOmMailbox.Headers][68]
7D097D [uMain.pas][uMain][uMain.TForm1.Button1Click][167]
543359 [Vcl.Controls][Vcl][Vcl.Controls.TControl.Click]
565BEF [Vcl.StdCtrls][Vcl][Vcl.StdCtrls.TCustomButton.Click]
5666FD [Vcl.StdCtrls][Vcl][Vcl.StdCtrls.TCustomButton.CNCommand]
542DE8 [Vcl.Controls][Vcl][Vcl.Controls.TControl.WndProc]

The block is currently used for an object of class: TTransfer

The allocation number is: 6233

Current memory dump of 256 bytes starting at pointer address 7EFA2A40:
68 F4 6C 00 80 D4 E6 7E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 B7 19 92 02 80 80 80 80 80 80 80 80 00 00 00 00 C1 2D FA 7E
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F0 18 00 00 06 6D 40 00 B7 88 40 00 DE 8F 40 00
11 D8 69 00 DE D5 69 00 B5 3A 7D 00 87 09 7D 00 59 33 54 00 EF 5B 56 00 FD 66 56 00 E8 2D 54 00
E4 36 00 00 E4 36 00 00 D5 88 40 00 29 90 40 00 FC FC 69 00 DB 89 40 00 5E 39 7D 00 95 34 7D 00
29 90 40 00 1D 2A 7D 00 B8 29 7D 00 84 2D 7D 00 DB 89 40 00 6C 00 00 00 68 F4 6C 00 64 EB 6A 87
h  ô  l  .  €  Ô  æ  ~  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
.  .  .  .  .  .  .  .  .  .  .  .  ·  .  ’  .  €  €  €  €  €  €  €  €  .  .  .  .  Á  -  ú  ~
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  ð  .  .  .  .  m  @  .  ·  ˆ  @  .  Þ    @  .
.  Ø  i  .  Þ  Õ  i  .  µ  :  }  .  ‡  .  }  .  Y  3  T  .  ï  [  V  .  ý  f  V  .  è  -  T  .
ä  6  .  .  ä  6  .  .  Õ  ˆ  @  .  )    @  .  ü  ü  i  .  Û  ‰  @  .  ^  9  }  .  •  4  }  .
)    @  .  .  *  }  .  ¸  )  }  .  „  -  }  .  Û  ‰  @  .  l  .  .  .  h  ô  l  .  d  ë  j  ‡

--------------------------------2014/10/20 10:52:37--------------------------------
This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):

37 - 52 bytes: TSQLRecordFill x 1
101 - 116 bytes: TTransfer x 1
485 - 532 bytes: Unknown x 1

Note: Memory leak detail is logged to a text file in the same folder as this application. To disable this memory leak check, undefine "EnableMemoryLeakReporting".

Please show me correct way to avoid the exception as well as the memory leak.

Thanks a lot for advance.

Offline

#2 2014-10-20 09:47:54

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

Re: How to avoid memory leak?

Your tr: TTransfer created in TOmMailbox.HeadersTable is never freed.
I suspect TOmMailbox.HeadersTable should return the TTransfer itself.
Then you would free this TTransfer, which would free its internal FillTable.

Offline

#3 2014-10-20 10:09:39

alexdmatveev
Member
Registered: 2014-09-12
Posts: 87

Re: How to avoid memory leak?

I am sorry...

I copied in the post wrong function.

function TOmMailbox.Headers(messageFormat: TOmMessageFormat): TTransfer;
begin
  if messageFormat = mtUnknown then
    Result := TTransfer.CreateAndFillPrepare(FClient, '')
  else
    Result := TTransfer.CreateAndFillPrepare(FClient, 'messageFormat=?', [Integer(messageFormat)]);
end;

So I return TTransfer object, but when I try to free it I get the exception.

Offline

#4 2014-10-20 10:31:25

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

Re: How to avoid memory leak?

You should free the record instance not the TSQLTable.

Offline

#5 2014-10-20 10:58:57

alexdmatveev
Member
Registered: 2014-09-12
Posts: 87

Re: How to avoid memory leak?

could you write me code snippet with my context?
what should I do concretely?

Thanks a lot for your help.

Offline

#6 2014-10-20 11:33:24

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

Re: How to avoid memory leak?

Please show your Button1click method code.
I will check it.

Offline

#7 2014-10-20 11:38:09

alexdmatveev
Member
Registered: 2014-09-12
Posts: 87

Re: How to avoid memory leak?

you will find it in topic starting post.

Offline

#8 2014-10-20 14:26:12

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

Re: How to avoid memory leak?

AFAIK it should not leak memory.
Ensure you are using the latest 1.18 revision, which is currently 1.18.359.

But the good way to retrieve a list is NOT to use such a temporary TSQLRecord instance, but directly TSQLRest.RetrieveList<TTransfer> method.

Offline

#9 2014-10-21 06:28:18

alexdmatveev
Member
Registered: 2014-09-12
Posts: 87

Re: How to avoid memory leak?

yes, with your TSQLRest.RetrieveList<TTransfer> approach it looks much more better.

Thanks a lot.

Offline

#10 2014-10-28 07:47:12

alexdmatveev
Member
Registered: 2014-09-12
Posts: 87

Re: How to avoid memory leak?

Let's up the topic again.

mormot has very comfortable way to sort JSONTable on client side, but I again have the memory leak as described above.

var
  transfer, headers: TTransfer;
  table: TSQLTable;
  objects: TObjectList<TTransfer>;
begin
  headers := TTransfer.CreateAndFillPrepare(FConnectionManager.LocalClient, 'messageFormat=?', [Integer(messageFormat)]);
  table := headers.FillTable;
  table.SortFields(0, false);
  objects := table.ToObjectList<TTransfer>;
  //do some with objects
  objects.Free;
  //headers.Free; <--EXCEPTION HERE
end;

I have to free [headers] object but when I try to do it I get exception about object is freed already.
But when I comment the row I have the leak as described above.

I would like to
1. sort
2. have not the memory leak

I use last night build downloaded yesterday.

What should I try?

Offline

#11 2014-10-28 14:38:26

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

Re: How to avoid memory leak?

Why not use FConnectionManager.LocalClient.MultiFieldValues() without any headers: TTransfer local variable?

Offline

#12 2014-10-28 15:38:33

alexdmatveev
Member
Registered: 2014-09-12
Posts: 87

Re: How to avoid memory leak?

MultiFieldValues looks like exactly what I need. Thanks a lot!

Offline

Board footer

Powered by FluxBB