Jump to content
djxandytche

Possible memory leak

Recommended Posts

Hello,
 

First of all I'd like to congratulate you on the excellent work you've done on P4D.
Secondly, I want to apologize for my bad English (I'm Brazilian and I'm using Google Translate to help).
 

I'm studying and testing P4D and I came across a situation that I couldn't understand.
The situation is a memory leak that occurs whenever the "ExecString" method is called to execute any script.
 

To simulate it, just do this simple example:

procedure TForm1.Button1Click(Sender: TObject);
var
    i: Integer;
begin
    for i := 1 to 1000 do
        GetPythonEngine.ExecString('print("hello")');
end;


I'm using Delphi 11.1 and compiling for 64-bit Windows.

For every 1000 scripts executed, memory consumption increases by about 0.5 MB.
In software that runs 100000 scripts per day, memory consumption could increase by around 50 MB per day.
I intend to use P4D in the software of the company I work for and in most cases it will exceed 100000 scripts executed per day and the executable will be running 24x7.
Considering this, I believe that at some point the memory may reach its limit.

Is there anything I can do to free up the memory consumed by each call to the "ExecString" method?

Thanks,

Alexandre da Silva.

Share this post


Link to post

Hi,

Do you mean capturing the output via "TPythonGUIInputOutput"?
If so: I'm not even using it.
I've made the code as simple as possible. See below:

Unit1.pas:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, PythonEngine;

type
  TForm1 = class(TForm)
    PythonEngine1: TPythonEngine;
    Memo1: TMemo;
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
    i: Integer;
begin
    for i := 1 to 1000 do
        GetPythonEngine.ExecString('print("hello")');
end;

end.


Unit1.dfm:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 234
  ClientWidth = 351
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -12
  Font.Name = 'Segoe UI'
  Font.Style = []
  TextHeight = 15
  object Label1: TLabel
    Left = 8
    Top = 8
    Width = 73
    Height = 15
    Caption = 'Python script:'
  end
  object Memo1: TMemo
    Left = 8
    Top = 29
    Width = 185
    Height = 89
    Lines.Strings = (
      'print("hello")')
    TabOrder = 0
  end
  object Button1: TButton
    Left = 8
    Top = 124
    Width = 185
    Height = 25
    Caption = 'Run 1000 times'
    TabOrder = 1
    OnClick = Button1Click
  end
  object PythonEngine1: TPythonEngine
    Left = 112
    Top = 48
  end
end


Is there something else I could be doing wrong?

Share this post


Link to post

This was a python reference counting issue.

Fixed in version control.

Please try the latest version and confirm the issue is solved.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×