Recent

Author Topic: [Solved] Memory Leak  (Read 429 times)

jshah

  • Full Member
  • ***
  • Posts: 170
[Solved] Memory Leak
« on: May 15, 2019, 11:11:54 pm »
Is heaptrc always show correct memory leak Why I am getting memory leak outside of my project

is there any way to find out which Object not free???

Code: Pascal  [Select]
  1. Heap dump by heaptrc unit
  2. 6484 memory blocks allocated : 2037813/2048320
  3. 6474 memory blocks freed     : 2037142/2047632
  4. 10 unfreed memory blocks : 671
  5. True heap size : 786432
  6. True free heap : 784192
  7. Should be : 784464
  8. Call trace for block $00007FFFE8456220 size 16
  9.   $000000000044CF34 line 649 of include/customform.inc
  10.   $0000000000430FDF
  11.   $000000000053FB6C line 5419 of include/wincontrol.inc
  12.   $000000000044EFCE line 1477 of include/customform.inc
  13.   $000000000054B876 line 1581 of include/control.inc
  14.   $000000000053D69E line 4385 of include/wincontrol.inc
  15.   $000000000053D5C7 line 4435 of include/wincontrol.inc
  16.   $000000000045295E line 2799 of include/customform.inc
  17. there is more..... like this
  18.  
« Last Edit: May 16, 2019, 12:06:39 pm by jshah »

ASBzone

  • Full Member
  • ***
  • Posts: 225
  • Automation leads to relaxation...
    • BrainWaveCC Utilities
Re: Memory Leak
« Reply #1 on: May 15, 2019, 11:28:01 pm »
Is heaptrc always show correct memory leak Why I am getting memory leak outside of my project

How are you adding/using heaptrc?

http://wiki.freepascal.org/heaptrc
-ASB: https://www.BrainWaveCC.com

Lazarus v2.0.3 r61159 / FPC v3.2.0-beta-r42011 (via FpcUpDeluxe) -- Windows 64-bit install w/32-bit cross-compile
Primary System: Windows 10 Pro x64, Version 1809 (Build 17763.379)
Other Systems: Windows 10 Pro x64, Version 1803 or greater

wp

  • Hero Member
  • *****
  • Posts: 5640
Re: Memory Leak
« Reply #2 on: May 15, 2019, 11:51:46 pm »
is there any way to find out which Object not free???

Code: Pascal  [Select]
  1. Heap dump by heaptrc unit
  2. 6484 memory blocks allocated : 2037813/2048320
  3. 6474 memory blocks freed     : 2037142/2047632
  4. 10 unfreed memory blocks : 671
  5. True heap size : 786432
  6. True free heap : 784192
  7. Should be : 784464
  8. Call trace for block $00007FFFE8456220 size 16
  9.   $000000000044CF34 line 649 of include/customform.inc
  10.   $0000000000430FDF
  11.   $000000000053FB6C line 5419 of include/wincontrol.inc
  12.   $000000000044EFCE line 1477 of include/customform.inc
  13.   $000000000054B876 line 1581 of include/control.inc
  14.   $000000000053D69E line 4385 of include/wincontrol.inc
  15.   $000000000053D5C7 line 4435 of include/wincontrol.inc
  16.   $000000000045295E line 2799 of include/customform.inc
  17. there is more..... like this
  18.  
Unfortunately you did not post all the lines of the heaptrc output. These lines refer to the stack of code lines which were involved in the allocation not freed. All the lines listed here are lines in the LCL which are called by your non-freed allocation - it's not guaranteed, but with high probability the LCL does not cause your memory leak. Therefore, you must go further down the list until you find a line of your code, maybe something like this:
Code: [Select]
....
  $(some hex number...) line 145 of unit1
From here you can tell that you created something in line 145 of unit1 which was not destroyed again. Just go to this line in this unit and you'll see the code which caused the memory leak.

For every unfreed memory block there is a group of lines "Call trace for block ..." in the heaptrc output. Often they report always the same memory leak because your program passed the leaky code several times.
« Last Edit: May 15, 2019, 11:54:23 pm by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

jshah

  • Full Member
  • ***
  • Posts: 170
Re: Memory Leak
« Reply #3 on: May 16, 2019, 12:03:24 am »
I am using project option -> Debugging -> use Heaptrc unit

here the full list


Code: Pascal  [Select]
  1. eap dump by heaptrc unit
  2. 6484 memory blocks allocated : 2037812/2048320
  3. 6474 memory blocks freed     : 2037141/2047632
  4. 10 unfreed memory blocks : 671
  5. True heap size : 786432
  6. True free heap : 784192
  7. Should be : 784464
  8. Call trace for block $00007FFFE8456220 size 16
  9.   $000000000044CF34 line 649 of include/customform.inc
  10.   $0000000000430FDF
  11.   $000000000053FB5C line 5419 of include/wincontrol.inc
  12.   $000000000044EFCE line 1477 of include/customform.inc
  13.   $000000000054B866 line 1581 of include/control.inc
  14.   $000000000053D68E line 4385 of include/wincontrol.inc
  15.   $000000000053D5B7 line 4435 of include/wincontrol.inc
  16.   $000000000045295E line 2799 of include/customform.inc
  17. Call trace for block $00007FFFED899000 size 73
  18.   $000000000044CF34 line 649 of include/customform.inc
  19.   $0000000000430FDF
  20.   $000000000053FB5C line 5419 of include/wincontrol.inc
  21.   $000000000044EFCE line 1477 of include/customform.inc
  22.   $000000000054B866 line 1581 of include/control.inc
  23.   $000000000053D68E line 4385 of include/wincontrol.inc
  24.   $000000000053D5B7 line 4435 of include/wincontrol.inc
  25.   $000000000045295E line 2799 of include/customform.inc
  26. Call trace for block $00007FFFE844C200 size 20
  27.   $000000000044CF34 line 649 of include/customform.inc
  28.   $0000000000430FDF
  29.   $000000000053FB5C line 5419 of include/wincontrol.inc
  30.   $000000000044EFCE line 1477 of include/customform.inc
  31.   $000000000054B866 line 1581 of include/control.inc
  32.   $000000000053D68E line 4385 of include/wincontrol.inc
  33.   $000000000053D5B7 line 4435 of include/wincontrol.inc
  34.   $000000000045295E line 2799 of include/customform.inc
  35. Call trace for block $00007FFFF7DFF2E0 size 384
  36.   $000000000044CF34 line 649 of include/customform.inc
  37.   $0000000000430FDF
  38.   $000000000053FB5C line 5419 of include/wincontrol.inc
  39.   $000000000044EFCE line 1477 of include/customform.inc
  40.   $000000000054B866 line 1581 of include/control.inc
  41.   $000000000053D68E line 4385 of include/wincontrol.inc
  42.   $000000000053D5B7 line 4435 of include/wincontrol.inc
  43.   $000000000045295E line 2799 of include/customform.inc
  44. Call trace for block $00007FFFE84560E0 size 16
  45.   $000000000044CF34 line 649 of include/customform.inc
  46.   $0000000000430FDF
  47.   $000000000053FB5C line 5419 of include/wincontrol.inc
  48.   $000000000044EFCE line 1477 of include/customform.inc
  49.   $000000000054B866 line 1581 of include/control.inc
  50.   $000000000053D68E line 4385 of include/wincontrol.inc
  51.   $000000000053D5B7 line 4435 of include/wincontrol.inc
  52.   $000000000045295E line 2799 of include/customform.inc
  53. Call trace for block $00007FFFED898BA0 size 56
  54.   $000000000044CF34 line 649 of include/customform.inc
  55.   $0000000000430FDF
  56.   $000000000053FB5C line 5419 of include/wincontrol.inc
  57.   $000000000044EFCE line 1477 of include/customform.inc
  58.   $000000000054B866 line 1581 of include/control.inc
  59.   $000000000053D68E line 4385 of include/wincontrol.inc
  60.   $000000000053D5B7 line 4435 of include/wincontrol.inc
  61.   $000000000045295E line 2799 of include/customform.inc
  62. Call trace for block $00007FFFE844C740 size 24
  63.   $000000000044CF34 line 649 of include/customform.inc
  64.   $0000000000430FDF
  65.   $000000000053FB5C line 5419 of include/wincontrol.inc
  66.   $000000000044EFCE line 1477 of include/customform.inc
  67.   $000000000054B866 line 1581 of include/control.inc
  68.   $000000000053D68E line 4385 of include/wincontrol.inc
  69.   $000000000053D5B7 line 4435 of include/wincontrol.inc
  70.   $000000000045295E line 2799 of include/customform.inc
  71. Call trace for block $00007FFFE8456180 size 16
  72.   $000000000044CF34 line 649 of include/customform.inc
  73.   $0000000000430FDF
  74.   $000000000053FB5C line 5419 of include/wincontrol.inc
  75.   $000000000044EFCE line 1477 of include/customform.inc
  76.   $000000000054B866 line 1581 of include/control.inc
  77.   $000000000053D68E line 4385 of include/wincontrol.inc
  78.   $000000000053D5B7 line 4435 of include/wincontrol.inc
  79.   $000000000045295E line 2799 of include/customform.inc
  80. Call trace for block $00007FFFE844C5C0 size 31
  81.   $000000000044CF34 line 649 of include/customform.inc
  82.   $0000000000430FDF
  83.   $000000000053FB5C line 5419 of include/wincontrol.inc
  84.   $000000000044EFCE line 1477 of include/customform.inc
  85.   $000000000054B866 line 1581 of include/control.inc
  86.   $000000000053D68E line 4385 of include/wincontrol.inc
  87.   $000000000053D5B7 line 4435 of include/wincontrol.inc
  88.   $000000000045295E line 2799 of include/customform.inc
  89. Call trace for block $00007FFFE844E480 size 35
  90.   $000000000044B7FD line 149 of include/customform.inc
  91.   $0000000000453D8B line 3184 of include/customform.inc
  92.   $000000000045DAB1 line 2241 of include/application.inc
  93.  

jshah

  • Full Member
  • ***
  • Posts: 170
Re: Memory Leak
« Reply #4 on: May 16, 2019, 12:20:58 am »
I have change optimization level to 0 here is new memory leak
Code: Pascal  [Select]
  1. Heap dump by heaptrc unit
  2. 6497 memory blocks allocated : 2038751/2049288
  3. 6487 memory blocks freed     : 2038080/2048600
  4. 10 unfreed memory blocks : 671
  5. True heap size : 786432
  6. True free heap : 784192
  7. Should be : 784464
  8. Call trace for block $00007FFFE8456220 size 16
  9.   $000000000044DCD4 line 1019 of include/customform.inc
  10.   $000000000044CF34 line 649 of include/customform.inc
  11.   $0000000000430FDF
  12.   $000000000053FB6C line 5419 of include/wincontrol.inc
  13.   $000000000044EFCE line 1477 of include/customform.inc
  14.   $000000000054B876 line 1581 of include/control.inc
  15.   $000000000053D69E line 4385 of include/wincontrol.inc
  16.   $000000000053D5C7 line 4435 of include/wincontrol.inc
  17. Call trace for block $00007FFFED899000 size 73
  18.   $000000000044DCD4 line 1019 of include/customform.inc
  19.   $000000000044CF34 line 649 of include/customform.inc
  20.   $0000000000430FDF
  21.   $000000000053FB6C line 5419 of include/wincontrol.inc
  22.   $000000000044EFCE line 1477 of include/customform.inc
  23.   $000000000054B876 line 1581 of include/control.inc
  24.   $000000000053D69E line 4385 of include/wincontrol.inc
  25.   $000000000053D5C7 line 4435 of include/wincontrol.inc
  26. Call trace for block $00007FFFE844C200 size 20
  27.   $000000000044DCD4 line 1019 of include/customform.inc
  28.   $000000000044CF34 line 649 of include/customform.inc
  29.   $0000000000430FDF
  30.   $000000000053FB6C line 5419 of include/wincontrol.inc
  31.   $000000000044EFCE line 1477 of include/customform.inc
  32.   $000000000054B876 line 1581 of include/control.inc
  33.   $000000000053D69E line 4385 of include/wincontrol.inc
  34.   $000000000053D5C7 line 4435 of include/wincontrol.inc
  35. Call trace for block $00007FFFF7DFF2E0 size 384
  36.   $000000000044DCD4 line 1019 of include/customform.inc
  37.   $000000000044CF34 line 649 of include/customform.inc
  38.   $0000000000430FDF
  39.   $000000000053FB6C line 5419 of include/wincontrol.inc
  40.   $000000000044EFCE line 1477 of include/customform.inc
  41.   $000000000054B876 line 1581 of include/control.inc
  42.   $000000000053D69E line 4385 of include/wincontrol.inc
  43.   $000000000053D5C7 line 4435 of include/wincontrol.inc
  44. Call trace for block $00007FFFE84560E0 size 16
  45.   $000000000044DCD4 line 1019 of include/customform.inc
  46.   $000000000044CF34 line 649 of include/customform.inc
  47.   $0000000000430FDF
  48.   $000000000053FB6C line 5419 of include/wincontrol.inc
  49.   $000000000044EFCE line 1477 of include/customform.inc
  50.   $000000000054B876 line 1581 of include/control.inc
  51.   $000000000053D69E line 4385 of include/wincontrol.inc
  52.   $000000000053D5C7 line 4435 of include/wincontrol.inc
  53. Call trace for block $00007FFFED898BA0 size 56
  54.   $000000000044DCD4 line 1019 of include/customform.inc
  55.   $000000000044CF34 line 649 of include/customform.inc
  56.   $0000000000430FDF
  57.   $000000000053FB6C line 5419 of include/wincontrol.inc
  58.   $000000000044EFCE line 1477 of include/customform.inc
  59.   $000000000054B876 line 1581 of include/control.inc
  60.   $000000000053D69E line 4385 of include/wincontrol.inc
  61.   $000000000053D5C7 line 4435 of include/wincontrol.inc
  62. Call trace for block $00007FFFE844C740 size 24
  63.   $000000000044DCD4 line 1019 of include/customform.inc
  64.   $000000000044CF34 line 649 of include/customform.inc
  65.   $0000000000430FDF
  66.   $000000000053FB6C line 5419 of include/wincontrol.inc
  67.   $000000000044EFCE line 1477 of include/customform.inc
  68.   $000000000054B876 line 1581 of include/control.inc
  69.   $000000000053D69E line 4385 of include/wincontrol.inc
  70.   $000000000053D5C7 line 4435 of include/wincontrol.inc
  71. Call trace for block $00007FFFE8456180 size 16
  72.   $000000000044DCD4 line 1019 of include/customform.inc
  73.   $000000000044CF34 line 649 of include/customform.inc
  74.   $0000000000430FDF
  75.   $000000000053FB6C line 5419 of include/wincontrol.inc
  76.   $000000000044EFCE line 1477 of include/customform.inc
  77.   $000000000054B876 line 1581 of include/control.inc
  78.   $000000000053D69E line 4385 of include/wincontrol.inc
  79.   $000000000053D5C7 line 4435 of include/wincontrol.inc
  80. Call trace for block $00007FFFE844C5C0 size 31
  81.   $000000000078DE85 line 50 of gui_home.pas
  82.   $000000000044DCD4 line 1019 of include/customform.inc
  83.   $000000000044CF34 line 649 of include/customform.inc
  84.   $0000000000430FDF
  85.   $000000000053FB6C line 5419 of include/wincontrol.inc
  86.   $000000000044EFCE line 1477 of include/customform.inc
  87.   $000000000054B876 line 1581 of include/control.inc
  88.   $000000000053D69E line 4385 of include/wincontrol.inc
  89. Call trace for block $00007FFFE844E480 size 35
  90.   $0000000000461E35 line 70 of gui_main.pas
  91.   $000000000044D9A5 line 939 of include/customform.inc
  92.   $000000000044B7FD line 149 of include/customform.inc
  93.   $0000000000453D8B line 3184 of include/customform.inc
  94.   $000000000045DAB1 line 2241 of include/application.inc
  95.   $000000000041E8EE line 18 of bmis_project.lpr
  96.  

Zoran

  • Hero Member
  • *****
  • Posts: 1357
    • http://wiki.lazarus.freepascal.org/User:Zoran
Re: Memory Leak
« Reply #5 on: May 16, 2019, 01:41:37 am »

These three look suspitious to me:
Code: Pascal  [Select]
  1.   $000000000078DE85 line 50 of gui_home.pas
  2.   $0000000000461E35 line 70 of gui_main.pas
  3.   $000000000041E8EE line 18 of bmis_project.lpr

First see what you have on line 18 of bmis_project.lpr, and see where it takes you. Some function is called there? Take a look.
Perhaps you call the same function in line 70 of gui_main and line 50 of gui_home?


jshah

  • Full Member
  • ***
  • Posts: 170
Re: Memory Leak
« Reply #6 on: May 16, 2019, 10:37:03 am »
$000000000041E8EE line 18 of bmis_project.lpr -> calling following
Application.CreateForm(TMainForm, MainForm);

$0000000000461E35 line 70 of gui_main.pas -> calling following
Login method of a class I have extracted suspicious line of code

Code: Pascal  [Select]
  1. before this  there is SQLquery  which select JSON stored in PG DB
  2. from that stored json i am creating a JSON OBJECT
  3.      self._PRVL  := TJSONObject.Create;
  4.       while rs.eof=false do begin
  5.         t_jobj := TJSONObject(GetJSON(rs.FieldByName('jdata').AsString));
  6.         t_jobj.Add('db_title', rs.FieldByName('db_caption').AsString);
  7.         self._PRVL.Add(rs.FieldByName('db_name').AsString,  t_jobj.Clone);
  8.         t_jobj.Free;
  9.         rs.next;
  10.       end;
  11.  

$000000000078DE85 line 50 of gui_home.pas -> calling following
Code: Pascal  [Select]
  1. function TBmisDb.get_allowed_db(): TJSONArray;
  2. var
  3.   i     : integer;
  4.   jobj  : TJSONObject;
  5.   t_db_name : string;
  6. begin
  7.   Result := TJSONArray.Create;
  8.   for i := 0 to self._PRVL.Count-1 do begin
  9.     t_db_name := self._PRVL.Names[i];
  10.  
  11.     jobj := self._PRVL.Objects[t_db_name];
  12.  
  13.     Result.Add(TJSONObject.Create);
  14.     Result.Objects[i].Add('db_title', jobj.Find('db_title').AsString);
  15.     Result.Objects[i].Add('db_name',  t_db_name);
  16.   end;
  17. end;
  18.  
  19.  

wp

  • Hero Member
  • *****
  • Posts: 5640
Re: Memory Leak
« Reply #7 on: May 16, 2019, 10:48:29 am »
Every "Create" must have an accomanying "Free" somewhere. Where is the "Free" which belongs to "self._PRVL  := TJSONObject.Create;" and "Result := TJSONArray.Create;"? And: I don't know what "t_jobj.Clone" is doing. If it creates another instance of "t_jobj" then it must be destoyed, too. This is a typical error made with TList and TStringList, etc: the user creates objects and adds them to these lists, but the user is not aware that the list does NOT destroy these objects automatically.
« Last Edit: May 16, 2019, 10:52:08 am by wp »
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

jshah

  • Full Member
  • ***
  • Posts: 170
Re: Memory Leak
« Reply #8 on: May 16, 2019, 10:57:57 am »
self._PRVL will be used by all over in application so this will be destroy when application close

which I am doing in class destroy method
FreeAndNil(self._PRVL);

I am copying JSON OBject from t_obj to main Structure self._PRVL (this hold big JSON object)

self._PRVL = LOOK LIKE ->
{"db_name1" : "BIG-JSON",  "db_name2" : "BIG-JSON", ....}

When we need to have the list of db we called :
Code: Pascal  [Select]
  1. procedure THomeForm.FormShow(Sender: TObject);
  2. var
  3.   jary : TJSONArray;
  4.   i : Integer;
  5. begin
  6.   try
  7.     jary := self.db_con.get_allowed_db();
  8.     for i := 0 to jary.Count-1 do begin
  9.       self.lstDb.AddItem(jary.Objects[i].Get('db_title'), jary[i].Clone);
  10.     end;
  11.   finally
  12.     jary.Free;
  13.   end;
  14. end;
  15.  

wp

  • Hero Member
  • *****
  • Posts: 5640
Re: Memory Leak
« Reply #9 on: May 16, 2019, 11:03:04 am »
Is the clone destroyed?

Here is a simple example:
Code: Pascal  [Select]
  1. type
  2.   TForm1 = class(TForm)
  3.     Button1: TButton;
  4.     procedure Button1Click(Sender: TObject);
  5.     procedure FormDestroy(Sender: TObject);
  6.   private
  7.     FList: TStringList;
  8.  
  9.   public
  10.  
  11.   end;
  12.  
  13. var
  14.   Form1: TForm1;
  15.  
  16. implementation
  17.  
  18. {$R *.lfm}
  19.  
  20. type
  21.   TInteger = class
  22.   private
  23.     FValue: Integer;
  24.   public
  25.     constructor Create(AValue: Integer);
  26.   end;
  27.  
  28. constructor TInteger.Create(AValue: Integer);
  29. begin
  30.   FValue := AValue;
  31. end;
  32.  
  33.  
  34. { TForm1 }
  35.  
  36. procedure TForm1.Button1Click(Sender: TObject);
  37. var
  38.   i: Integer;
  39. begin
  40.   if FList = nil then
  41.     FList := TStringList.Create;
  42.   for i:=0 to 10 do
  43.     FList.AddObject(IntToStr(i), TInteger.Create(i));
  44. end;
  45.  
  46. { Version WITH memory leak
  47. procedure TForm1.FormDestroy(Sender: TObject);
  48. begin
  49.   FList.Free;
  50. end;                       }
  51.  
  52. { Version WITHOUT memory leak }
  53. procedure TForm1.FormDestroy(Sender: TObject);
  54. var
  55.   i: Integer;
  56. begin
  57.   if FList <> nil then
  58.     for i := 0 to FList.Count-1 do
  59.       TObject(FList.Objects[i]).Free;
  60.   FreeAndNil(FList);
  61. end;  
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

jshah

  • Full Member
  • ***
  • Posts: 170
Re: Memory Leak
« Reply #10 on: May 16, 2019, 11:19:39 am »
self.lstDB -> Gui components TListBox

Do i have to destroy the Object from TListBox also

jshah

  • Full Member
  • ***
  • Posts: 170
Re: Memory Leak [This is Solution]
« Reply #11 on: May 16, 2019, 11:24:29 am »
Yes that is the issue.

I thought TListBox will destroy associated object with it.

We need to destroy associated object manually.
« Last Edit: May 16, 2019, 12:06:18 pm by jshah »

jshah

  • Full Member
  • ***
  • Posts: 170
Re: Memory Leak
« Reply #12 on: May 16, 2019, 11:31:11 am »
Thanks WP for your time and patience

Thanks Zoran
« Last Edit: May 16, 2019, 12:05:08 pm by jshah »

jshah

  • Full Member
  • ***
  • Posts: 170
Re: Memory Leak
« Reply #13 on: May 16, 2019, 12:04:37 pm »
This corrected my other program also which was leaking memory

wp

  • Hero Member
  • *****
  • Posts: 5640
Re: Memory Leak [This is Solution]
« Reply #14 on: May 16, 2019, 12:56:52 pm »
I thought TListBox will destroy associated object with it.
The principle is: The one who created an object, allocated memory etc, must also destroy it/release it - YOU created the objects for the listbox - YOU destroy them.
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10