Delphi Pages Forums  

Go Back   Delphi Pages Forums > Delphi Forum > General

Lost Password?

Closed Thread
 
Thread Tools Display Modes
  #1  
Old 03-23-2016, 03:39 PM
FreakaZoid2 FreakaZoid2 is offline
Senior Member
 
Join Date: Jul 2009
Posts: 362
Default Delphi Seattle FireDac, Why memory leak in code?

I have the following code getting reported with a memory leak via FastMM.
Code:
      if not(dmClaims.fdqryLawyers.FieldByName(dmClaims.fdqryLawyers.FieldList[I].FieldName).IsNull) then
      begin
        _wic := TWICImage.Create;
        _wic.LoadFromStream(dmClaims.fdqryLawyers.CreateBlobStream(dmClaims.fdqryLawyers.FieldByName(dmClaims.fdqryLawyers.FieldList[I].FieldName),TBlobStreamMode.bmRead));
        SearchAndReplaceImage('<' + dmClaims.fdqryLawyers.FieldList[I].FieldName + '>', _wic);
        FreeAndNil(_wic);
      end;
  #2  
Old 03-23-2016, 03:43 PM
FreakaZoid2 FreakaZoid2 is offline
Senior Member
 
Join Date: Jul 2009
Posts: 362
Default Here is FastMM report...

A memory block has been leaked. The size is: 52

This block was allocated by thread 0x1D2C, and the stack trace (return addresses) at the time was:
406EB6 [System.pas][System][@GetMem$qqri][4602]
408003 [System.pas][System][TObject.NewInstance$qqrv][16184]
40880E [System.pas][System][@ClassCreate$qqrpvzc][17499]
889E7F [FireDAC.Comp.DataSet.pas][FireDAC.Comp.DataSet][Comp.Dataset.TFDBlobStream.$bctr$qqrp14Data.Db.TFi eld23Data.Db.TBlobStreamMode][8325]
6C0FA4 [Data.DB.pas][Data.DB][Db.TFields.FindField$qqrx20System.UnicodeString][4615]
6D4818 [Data.DB.pas][Data.DB][Db.TDataSet.FieldByName$qqrx20System.UnicodeString][13110]
88145F [FireDAC.Comp.DataSet.pas][FireDAC.Comp.DataSet][Comp.Dataset.TFDDataSet.CreateBlobStream$qqrp14Dat a.Db.TField23Data.Db.TBlobStreamMode][4290]
B62597 [fDocuments.pas][fDocuments][TfrmDocuments.ProcessDocument$qqrv][739]
B5E2F7 [fDocuments.pas][fDocuments][TfrmDocuments.sbtnSaveClick$qqrp14System.TObject][342]
54DCD9 [Vcl.Controls.pas][Vcl.Controls][Controls.TControl.Click$qqrv][7365]
68EFCF [JvSpeedButton][TJvCustomSpeedButton.Click$qqrv]

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

The allocation number is: 85583

Current memory dump of 256 bytes starting at pointer address 7F418B10:
8C A0 87 00 20 78 40 7F 23 24 00 00 23 24 00 00 00 00 00 00 00 E2 43 7F 20 AD CB 7F B8 BE 7B 7F
00 00 00 00 00 00 00 00 CD A7 F9 75 80 80 80 80 80 80 80 80 80 80 80 80 00 00 00 00 91 90 41 7F
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CC 01 06 00 B6 6E 40 00 BF 9E 40 00 96 B3 40 00
48 07 6C 00 D8 28 B6 00 F7 E2 B5 00 D9 DC 54 00 CF EF 68 00 C9 F3 68 00 CA F7 68 00 11 E1 54 00
2C 1D 00 00 2C 1D 00 00 D2 6E 40 00 DE 9F 40 00 BA 45 B6 00 F7 E2 B5 00 D9 DC 54 00 CF EF 68 00
C9 F3 68 00 CA F7 68 00 11 E1 54 00 91 E1 54 00 68 D7 54 00 26 00 00 00 B0 04 02 00 5E C3 43 88
98 12 BB 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 A1 3C BC 77 80 80 80 80 80 80 80 80 80 80 80 80 80 80 00 00 00 00 91 81 41 7F
. x @  # $ . . # $ . . . . . . . C  *  { 
. . . . . . . . u . . . . A 
. . . . . . . . . . . . . . . . . . . n @ . @ . @ .
H . l . ( . . T . h . h . h . . T .
, . . . , . . . n @ . @ . E . . T . h .
h . h . . T . T . h T . & . . . . . . ^ C
. .
< w . . . . A 
  #3  
Old 03-23-2016, 03:58 PM
Norrit Norrit is offline
Moderator
 
Join Date: Aug 2001
Location: Landgraaf
Posts: 7,335
Default

My guess is this line:
Code:
_wic.LoadFromStream(dmClaims.fdqryLawyers.CreateBlobStream(dmClaims.fdqryLawyers.FieldByName(dmClaims.fdqryLawyers.FieldList[I].FieldName),TBlobStreamMode.bmRead));
If you split it you'll get:
Code:
blobStream := dmClaims.fdqryLawyers.CreateBlobStream(dmClaims.fdqryLawyers.FieldByName(dmClaims.fdqryLawyers.FieldList[I].FieldName),TBlobStreamMode.bmRead);
_wic.LoadFromStream(blobStream);
blobStream.Free();
As you can see the CreateBlobStream returns a stream (so it creates one), and that's the only thing you don't .Free() in your construction

NB: FreeAndNil(x) is useless if you don't validate any further on nil, only .Free() is sufficient. And if you're a purist, then it should be in a finally ;-)
  #4  
Old 03-23-2016, 04:27 PM
FreakaZoid2 FreakaZoid2 is offline
Senior Member
 
Join Date: Jul 2009
Posts: 362
Default Yeah I tried going down that road already.

Looks like it is some kind of memory leak in FireDac to me...
Code:
      if not(dmClaims.fdqryLawyers.FieldByName(dmClaims.fdqryLawyers.FieldList[I].FieldName).IsNull) then
      begin
        _wic := TWICImage.Create;
        _bStream := dmClaims.fdqryLawyers.CreateBlobStream(dmClaims.fdqryLawyers.FieldByName(dmClaims.fdqryLawyers.FieldList[I].FieldName),TBlobStreamMode.bmRead);
        _wic.LoadFromStream(_bStream);
        SearchAndReplaceImage('<' + dmClaims.fdqryLawyers.FieldList[I].FieldName + '>', _wic);
        FreeAndNil(_wic);
        _bStream.Free;
      end;
--------------------------------2016/3/23 9:35:41--------------------------------
A memory block has been leaked. The size is: 52

This block was allocated by thread 0x1D2C, and the stack trace (return addresses) at the time was:
406EB6 [System.pas][System][@GetMem$qqri][4602]
408003 [System.pas][System][TObject.NewInstance$qqrv][16184]
40880E [System.pas][System][@ClassCreate$qqrpvzc][17499]
889E7F [FireDAC.Comp.DataSet.pas][FireDAC.Comp.DataSet][Comp.Dataset.TFDBlobStream.$bctr$qqrp14Data.Db.TFi eld23Data.Db.TBlobStreamMode][8325]
6C0FA4 [Data.DB.pas][Data.DB][Db.TFields.FindField$qqrx20System.UnicodeString][4615]
6D4818 [Data.DB.pas][Data.DB][Db.TDataSet.FieldByName$qqrx20System.UnicodeString][13110]
88145F [FireDAC.Comp.DataSet.pas][FireDAC.Comp.DataSet][Comp.Dataset.TFDDataSet.CreateBlobStream$qqrp14Dat a.Db.TField23Data.Db.TBlobStreamMode][4290]
B62597 [fDocuments.pas][fDocuments][TfrmDocuments.ProcessDocument$qqrv][739]
B5E2F7 [fDocuments.pas][fDocuments][TfrmDocuments.sbtnSaveClick$qqrp14System.TObject][342]
54DCD9 [Vcl.Controls.pas][Vcl.Controls][Controls.TControl.Click$qqrv][7365]
68EFCF [JvSpeedButton][TJvCustomSpeedButton.Click$qqrv]

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

The allocation number is: 85583

Current memory dump of 256 bytes starting at pointer address 7F418B10:
8C A0 87 00 20 78 40 7F 23 24 00 00 23 24 00 00 00 00 00 00 00 E2 43 7F 20 AD CB 7F B8 BE 7B 7F
00 00 00 00 00 00 00 00 CD A7 F9 75 80 80 80 80 80 80 80 80 80 80 80 80 00 00 00 00 91 90 41 7F
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CC 01 06 00 B6 6E 40 00 BF 9E 40 00 96 B3 40 00
48 07 6C 00 D8 28 B6 00 F7 E2 B5 00 D9 DC 54 00 CF EF 68 00 C9 F3 68 00 CA F7 68 00 11 E1 54 00
2C 1D 00 00 2C 1D 00 00 D2 6E 40 00 DE 9F 40 00 BA 45 B6 00 F7 E2 B5 00 D9 DC 54 00 CF EF 68 00
C9 F3 68 00 CA F7 68 00 11 E1 54 00 91 E1 54 00 68 D7 54 00 26 00 00 00 B0 04 02 00 5E C3 43 88
98 12 BB 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 A1 3C BC 77 80 80 80 80 80 80 80 80 80 80 80 80 80 80 00 00 00 00 91 81 41 7F
. x @  # $ . . # $ . . . . . . . C  *  { 
. . . . . . . . u . . . . A 
. . . . . . . . . . . . . . . . . . . n @ . @ . @ .
H . l . ( . . T . h . h . h . . T .
, . . . , . . . n @ . @ . E . . T . h .
h . h . . T . T . h T . & . . . . . . ^ C
. .
< w . . . . A 
  #5  
Old 03-23-2016, 04:37 PM
FreakaZoid2 FreakaZoid2 is offline
Senior Member
 
Join Date: Jul 2009
Posts: 362
Default Nevermind

Cranal Rectal inversion.
Looking at the log file from FastMM it just appends to the end of the log.
It is working fine the way you recommended...
  #6  
Old 03-23-2016, 06:22 PM
rojam rojam is offline
Senior Member
 
Join Date: Jun 2015
Posts: 200
Default

you should also protect against memory leaks with try finally blocks. Any error that occurs between when you create the wicimage / blobstream and their corresponding .free will never execute.
Code:
_wic := TWICImage.Create;
try
  _bStream := dmClaims.fdqryLawyers.CreateBlobStream(dmClaims.fdqryLawyers.FieldByName(dmClaims.fdqryLawyers.FieldList[I].FieldName),TBlobStreamMode.bmRead);
  try
    _wic.LoadFromStream(_bStream);
    SearchAndReplaceImage('<' + dmClaims.fdqryLawyers.FieldList[I].FieldName + '>', _wic);
  finally 
    _bStream.Free;
  end;
finally
  _wic.Free;
end;
Closed Thread

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On

Forum Jump


All times are GMT. The time now is 08:38 PM.


Powered by vBulletin® Version 3.8.8
Copyright ©2000 - 2019, vBulletin Solutions, Inc.