RemoteDB Indy server on Linux 20.04 gets too high mem usage

Hi I have RemoteDB Indy server on LInux 20.04, database is Firebird 3.5 (standard package of Linux). Data access is UniDAC 9.1. All are latest version. It starts using pm2. If it's running on Windows, mem usage is only 5MB but on Linux it always gets 665MB memory and it runs slowly. Please help what is the reason and what to do to solve it?

MacsRemoteLinux.dpr (682 Bytes)
Server.pas (1.5 KB)
ConnectionModule.dfm (904 Bytes)
ConnectionModule.pas (5.0 KB)

Your application uses several 3rd party components (Indy, RemoteDB, UniDAC), and it's not clear what client operations you perform to increase the memory.
I'm afraid you will have to inspect it more to better isolate the problem - it might be anywhere.
First suggestion is that you use a memory leak detection tool (I suggest Valgrind: Catching memory leaks in Delphi: list of tools | landgraf.dev) to get more information about if and where the memory is leaking.

unit Server;

interface
uses
RemoteDB.Server.Module,
System.SysUtils,
ConnectionModule,
IniFiles,
Sparkle.Middleware.Cors,
Sparkle.Middleware.Compress,
Sparkle.HttpServer.Context,
Sparkle.HttpServer.Module,
Sparkle.Indy.Server;

procedure StartServer;
procedure StopServer;

implementation
uses System.IOUtils;

var
SparkleServer: TIndySparkleHTTPServer;

procedure StartServer;
var
AIniFile:TIniFile;
I,PortNo:Integer;
DbCount:Integer;
Fconnection: Tdm1;
begin
if Assigned(SparkleServer) then
Exit;

CashConfFile := ParamStr(0);
CashConfFile := ExtractFilePath(CashConfFile) + 'SyncConfig.ini';

AIniFile := TIniFile.Create(CashConfFile);
try

PortNo := AIniFile.ReadInteger('Application', 'Port', 8881);

DBcount := AIniFile.ReadInteger('Application', 'DBCount', 1);
if DBcount= 0 then
  AIniFile.WriteInteger('Application', 'DBCount', 1);

finally
AIniFile.Free;
end;
SparkleServer := TIndySparkleHTTPServer.Create(nil);

SparkleServer.DefaultPort := PortNo;

for I := 1 to DbCount do begin
Fconnection := Tdm1.Create(nil);
Fconnection.ConnectionProps(I,PortNo,SparkleServer);
end;

SparkleServer.Active := True;
end;

procedure StopServer;
begin
FreeAndNil(SparkleServer);
end;

initialization
SparkleServer := nil;
finalization
StopServer;
end.


unit ConnectionModule;

interface

uses
System.SysUtils, System.Classes, PostgreSQLUniProvider, UniProvider,
InterBaseUniProvider, Data.DB, DBAccess, Uni,Aurelius.Drivers.Base,
Sparkle.Indy.Server,iniFiles,Aurelius.Drivers.Interfaces,
RemoteDB.Server.Module, Aurelius.Sql.Firebird, Aurelius.Schema.Firebird,
Aurelius.Drivers.UniDac, Aurelius.Comp.Connection, Sparkle.Comp.Server,
RemoteDB.Comp.Server, Sparkle.HttpServer.Module, Sparkle.HttpServer.Context;

const
ServerUrl = 'http://localhost:8881/macs/';

type
Tdm1 = class(TDataModule)
UniConnection: TUniConnection;
InterBaseUniProvider1: TInterBaseUniProvider;
AureliusConnection1: TAureliusConnection;
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
procedure RemoteDBServer1BeforeStatement(Info: IStatementInfo);
procedure UniConnectionError(Sender: TObject; E: EDAError;
var Fail: Boolean);
private
{ Private declarations }
procedure SetIBConnection(DBPath: String);
public
{ Public declarations }
function CreateConnection: IDBConnection;
function CreateFactory: IDBConnectionFactory;
procedure ConnectionProps(AIndex,PortNo:Integer;dispatcher:TIndySparkleHTTPServer);
end;

var
dm1: Tdm1;
CashConfFile :String;

procedure AddLog(AText:String);
procedure CreateTextFile(Filename : string);

implementation

{%CLASSGROUP 'System.Classes.TPersistent'}

{$R *.dfm}

procedure Tdm1.ConnectionProps(AIndex,PortNo:Integer;dispatcher:TIndySparkleHTTPServer);
var
AIniFile:TIniFile;
DBPath,DBName,Section,ServerName:String;
port:Integer;
baseurl,Password,fbClientLibrary:String;
module:TRemoteDBModule;
begin
AIniFile := TIniFile.Create(CashConfFile);
try
Section := 'Database_'+ AIndex.ToString;

ServerName := AIniFile.ReadString(Section, 'Servername', '');
DBPath := AIniFile.ReadString(Section, 'DBPath', '');
DBName := AIniFile.ReadString(Section, 'DBName', '');
Password := AIniFile.ReadString(Section, 'Password', 'password');
fbClientLibrary := AIniFile.ReadString(Section, 'ClientLibrary', '');
port := AIniFile.ReadInteger(Section, 'Port', 3051);
UniConnection.Password := Password;
UniConnection.Port := Port;
UniConnection.Server :=ServerName;

baseurl := StringReplace(ServerUrl,'8881',portNo.ToString,[rfReplaceAll]);
baseurl := baseurl + DBName;

AddLog(baseurl);

AureliusConnection1.SQLDialect := 'Firebird';
SetIBConnection(DBPAth);


{if (ACharset = mcutf8) and (fbClientLibrary<>'') then
  UniConnection1.SpecificOptions.Values['ClientLibrary'] := fbClientLibrary;
else
  UniConnection1.SpecificOptions.Values['ClientLibrary'] := ''; }
module := TRemoteDBModule.Create(baseurl, CreateFactory);
dispatcher.Dispatcher.AddModule(module);

finally
AIniFile.Free;
end;
end;

procedure Tdm1.RemoteDBServer1BeforeStatement(Info: IStatementInfo);
begin
Writeln(info.Sql);
end;

procedure Tdm1.SetIBConnection(DBPath:String);
begin
UniConnection.SpecificOptions.Values['Charset'] := 'utf8';
UniConnection.SpecificOptions.Values['SQLDialect'] := '1';
UniConnection.Database := DBPath;

UniConnection.LoginPrompt := false;
UniConnection.Username := 'sysdba';
end;

procedure Tdm1.UniConnectionError(Sender: TObject; E: EDAError;
var Fail: Boolean);
begin
AddLog(e.Message);
end;

procedure AddLog(AText:String);
var
ss:String;
myFile : TextFile;
begin
ss := ExtractFilePath(paramstr(0)) + 'ConnectLog.txt';
if not FileExists(ss) then
CreateTextFile(ss);

AssignFile(myFile, SS);
Append(myFile);
WriteLn(myFile, AText);
WriteLn(AText);
CloseFile(myFile);
end;

procedure Tdm1.DataModuleCreate(Sender: TObject);
begin
AddLog('Session create at ' + DateTimeToStr(Now));
end;

procedure Tdm1.DataModuleDestroy(Sender: TObject);
begin
Writeln('Session destroy at ' + DateTimeToStr(Now));
end;

procedure CreateTextFile(Filename : string);
var FS : TFileStream;
begin
FS := TFileStream.Create(Filename, fmCreate);
FreeAndNil(FS);
end;

function Tdm1.CreateConnection: IDBConnection;
begin
Result := AureliusConnection1.CreateConnection;
end;

function Tdm1.CreateFactory: IDBConnectionFactory;
begin
Result := TDBConnectionFactory.Create(
function: IDBConnection
begin
Result := CreateConnection;
end
);
end;

end.

I'm sorry, what does this mean and how does it relate with my previous comments?