Recent

Author Topic: Any idea how can I prevent Memory leaks?  (Read 1131 times)

Joachim

  • Newbie
  • Posts: 1
Any idea how can I prevent Memory leaks?
« on: December 11, 2019, 09:41:37 am »
Hello Friends,

Any idea how can I prevent memory leaks? It's causing great issue for me.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7853
Re: Any idea how can I prevent Memory leaks?
« Reply #1 on: December 11, 2019, 10:09:04 am »
Any idea how can I prevent memory leaks? It's causing great issue for me.

Deallocate the relevant classes and other allocations. If you have problems with a specific case, you need to specify more about it.

PaulRowntree

  • Full Member
  • ***
  • Posts: 108
    • Paul Rowntree
Re: Any idea how can I prevent Memory leaks?
« Reply #2 on: December 13, 2019, 04:41:48 am »
Hello Friends,

Any idea how can I prevent memory leaks? It's causing great issue for me.
If itis an  object based leak, you should carefully review your Destructor codes ... something is not being released properly.
Do you do any memory allocation, or do you suspect underlying provided codes?
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems

Zvoni

  • Sr. Member
  • ****
  • Posts: 308
Re: Any idea how can I prevent Memory leaks?
« Reply #3 on: December 13, 2019, 09:25:26 am »
Hello Friends,

Any idea how can I prevent memory leaks? It's causing great issue for me.

Use proper sealing.....
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircrafts

howardpc

  • Hero Member
  • *****
  • Posts: 3280
Re: Any idea how can I prevent Memory leaks?
« Reply #4 on: December 13, 2019, 12:03:44 pm »
In the Options for Project: xxx dialog for your project, click the Debugging node and make sure in the Other debugging info section that you have checked the Use Heaptrc unit (check for mem-leaks) (-gh) checkbox.
This gives you a dialog (on Windows) or console listing after your program runs and exits. If there are leaks, the list will help you identify which lines in your code are giving rise to them.

wp

  • Hero Member
  • *****
  • Posts: 6654
Re: Any idea how can I prevent Memory leaks?
« Reply #5 on: December 13, 2019, 12:58:32 pm »
Maybe it is instructive to illustrate Howard's post by an example - see attached project.

When the button is clicked a StringList is created, some items are added, and the StringList is assigned to the Items of a Listbox for display.

The program runs fine, but it creates a memory leak because the List is not destroyed at the end of the Button1Click method.

When "Use Heaptrc unit (check from mem-leaks) (-gh)" is checked in the Project options / Debugging a long list of addresses is displayed when the program ends. When you also have checked "Display line numbers in run-time error backtraces (-gl)" information on the code lines are displayed along with the addresses whenever possible.

The heaptrc output is displayed in the attached screenshot. It is a bit overwhelming, I agree, because it contains all the locations affected by the memory leak(s). But when you scan through the lines you'll see "TFORM1_BUTTON1CLICK, line 37 of unit1.pas". This is exactly where the memory leak was created: an object was created but never destroyed.

When you add "List.Free" at the end of the procedure and run again heaptrc reports "0 freed memory blocks" -- this is the success message that the memory leak has been fixed (although the dialog is titled "Error"...).
Lazarus trunk / fpc 3.0.4 / all 32-bit on Win-10

PaulRowntree

  • Full Member
  • ***
  • Posts: 108
    • Paul Rowntree
Re: Any idea how can I prevent Memory leaks?
« Reply #6 on: December 13, 2019, 04:11:55 pm »
I always thought that objects were automatically released when they went out of scope.  Is this just Pascal Objects, and not instances of a class (like the List object in your example)?
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems

mr-highball

  • Full Member
  • ***
  • Posts: 104
Re: Any idea how can I prevent Memory leaks?
« Reply #7 on: December 13, 2019, 04:21:43 pm »
class instances are not freed automatically when they go out of scope, but old school "objects" are since they're stack allocated like records (unless of course the new keyword is used)
see this for more info on that -> https://wiki.freepascal.org/Object

As far as the original question, heaptrc is always a good option, but also designing libaries/applications using interfaces is a good way to avoid leaks since they're automatically reference counted and once the last reference goes out of scope, the destructor code is called.
-Highball

PaulRowntree

  • Full Member
  • ***
  • Posts: 108
    • Paul Rowntree
Re: Any idea how can I prevent Memory leaks?
« Reply #8 on: December 13, 2019, 06:07:58 pm »
class instances are not freed automatically when they go out of scope, but old school "objects" are since they're stack allocated like records (unless of course the new keyword is used)
see this for more info on that -> https://wiki.freepascal.org/Object
Thanks mr-highball!  Time to review a lot of code ...
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7853
Re: Any idea how can I prevent Memory leaks?
« Reply #9 on: December 13, 2019, 06:23:18 pm »
Strictly speaking there are no automatically deallocated objects in Pascal.

Yes, TP object declaration are autocleaning, but you can't use any form of polymorphism when used statically, so even though called "object", they aren't.

howardpc

  • Hero Member
  • *****
  • Posts: 3280
Re: Any idea how can I prevent Memory leaks?
« Reply #10 on: December 13, 2019, 07:17:38 pm »
I always thought that objects were automatically released when they went out of scope.  Is this just Pascal Objects, and not instances of a class (like the List object in your example)?
The LCL (based on the VCL model) does provide automatic release of a particular group of classes provided:
  • The class descends from TComponent
  • The instance is given a non-Nil Owner in its constructor
With those two provisos, the responsibility for freeing the instance is passed to the instance's Owner, and the programmer can forget about it.
Indeed, it is an error to manually Free such an instance.

mr-highball

  • Full Member
  • ***
  • Posts: 104
Re: Any idea how can I prevent Memory leaks?
« Reply #11 on: December 13, 2019, 07:24:31 pm »
To add on my reference of using interfaces, I thought an example would be good to demonstrate that even though automatic reference counting frees the implementation class, forgetting to free class instances (in this example a string list property) can still result in leaks.

Code: Pascal  [Select]
  1. {$Mode delphi}
  2. program Project1;
  3. uses
  4.   Classes;
  5.  
  6. type
  7.  
  8.   { ITestInterface }
  9.  
  10.   ITestInterface = interface
  11.     ['{E634371B-7235-457C-A97C-2638F80F7680}']
  12.     //property methods
  13.     function GetList: TStringList;
  14.  
  15.     //properties
  16.     property List : TStringList read GetList;
  17.   end;
  18.  
  19.   { TLeakyTestInterfaceImpl }
  20.  
  21.   TLeakyTestInterfaceImpl = class(TInterfacedObject, ITestInterface)
  22.   strict private
  23.     FList : TStringList;
  24.   private
  25.     function GetList: TStringList;
  26.   public
  27.     property List : TStringList read GetList;
  28.  
  29.     constructor Create;
  30.     destructor Destroy; override;
  31.   end;
  32.  
  33.   { TPluggedLeakTestInterfaceImpl }
  34.  
  35.   TPluggedLeakTestInterfaceImpl = class(TInterfacedObject, ITestInterface)
  36.   strict private
  37.     FList : TStringList;
  38.   private
  39.     function GetList: TStringList;
  40.   public
  41.     property List : TStringList read GetList;
  42.  
  43.     constructor Create;
  44.     destructor Destroy; override;
  45.   end;
  46.  
  47. { TPluggedLeakTestInterfaceImpl }
  48.  
  49. function TPluggedLeakTestInterfaceImpl.GetList: TStringList;
  50. begin
  51.   Result := FList;
  52. end;
  53.  
  54. constructor TPluggedLeakTestInterfaceImpl.Create;
  55. begin
  56.   FList := TStringList.Create;
  57. end;
  58.  
  59. destructor TPluggedLeakTestInterfaceImpl.Destroy;
  60. begin
  61.   //unlike the leaky example, this one properly frees the list
  62.   FList.Free;
  63.   inherited Destroy;
  64. end;
  65.  
  66. { TLeakyTestInterfaceImpl }
  67.  
  68. function TLeakyTestInterfaceImpl.GetList: TStringList;
  69. begin
  70.   Result := FList;
  71. end;
  72.  
  73. constructor TLeakyTestInterfaceImpl.Create;
  74. begin
  75.   FList := TStringList.Create;
  76. end;
  77.  
  78. destructor TLeakyTestInterfaceImpl.Destroy;
  79. begin
  80.   //instead of freeing this object, our "list" will be leaked
  81.   inherited Destroy;
  82. end;
  83.  
  84. ////////////////////////////////////////////////////////////////////////////////
  85. //EXAMPLE
  86. //demonstration of using interfaces that will be freed automatically once
  87. //all references go out of scope. we show that proper destructor code
  88. //still needs to be used though, otherwise we will leak memory
  89. ////////////////////////////////////////////////////////////////////////////////
  90. var
  91.   LLeaky,
  92.   LPluggedLeak : ITestInterface;
  93. begin
  94.   //initialize both types of implementations
  95.   LLeaky := TLeakyTestInterfaceImpl.Create; //leaks List by not freeing in destructor
  96.   LPluggedLeak := TPluggedLeakTestInterfaceImpl.Create; //frees list in destructor
  97.  
  98.   //after this "end" both interfaces classes will be freed because
  99.   //there are no references
  100. end.
  101.  
  102.  
-Highball

MarkMLl

  • Hero Member
  • *****
  • Posts: 608
Re: Any idea how can I prevent Memory leaks?
« Reply #12 on: December 13, 2019, 07:30:45 pm »
I always thought that objects were automatically released when they went out of scope.  Is this just Pascal Objects, and not instances of a class (like the List object in your example)?

I'm afraid that that only applies to managed types such as strings and dynamic arrays, not to objects (instances of classes) per se.

Objects are neither subject to deallocation when they go out of scope, nor to periodic garbage collection when they are no longer referenced.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.

sash

  • Sr. Member
  • ****
  • Posts: 325
Re: Any idea how can I prevent Memory leaks?
« Reply #13 on: December 14, 2019, 06:50:17 pm »
I always thought that objects were automatically released when they went out of scope.

Pascal's objects are similar to C++'s class pointers: allocated on heap.

Cons: you have to free them.
Pros: they can be passed across scopes (without pointer syntax).
Lazarus 2.0.6 FPC 3.0.4 x86_64-linux-gtk2 @ Ubuntu 19.10 XFCE

del

  • Full Member
  • ***
  • Posts: 158
Re: Any idea how can I prevent Memory leaks?
« Reply #14 on: December 24, 2019, 10:16:44 am »
I always thought that objects were automatically released when they went out of scope.  Is this just Pascal Objects, and not instances of a class (like the List object in your example)?
That's C++.