I have some questions about Linux & ARC and I'm hoping some experts can share their expertise because I'm not understand the results I'm seeing.

I have some questions about Linux & ARC and I'm hoping some experts can share their expertise because I'm not understand the results I'm seeing.

For the first example, I have a simple console application making use of Devart's Postgres database controls...

This code just chews up more and more memory and makes more and more connections to the postgres server until the server cannot accept anymore connections. This appears to be because 'free' no longer actually works.

I appreciate that .disposeOf works in this code, but I'm trying to understand if the vendor really needs to go and replace every 'free' with disposeOf (and in theory we do as well) and why this particular code which to me seems simple doesn't ever kill any of the objects created.

I appreciate databases would normally be used in thread pools, I pulled this out of a thread pool to try and debug the underlying object due to the memory leak in the thread pool.

program TPgMemLeak2;

{$APPTYPE CONSOLE}

{$R *.res}


uses
System.SysUtils,
System.Classes,
PgAccess;


procedure newTask( value: integer );
var
pgConnection: TPgConnection;
pgQuery: TPgQuery;
begin
pgConnection := TPgConnection.Create(nil);
pgConnection.Server := server;
pgConnection.Username := user;
pgConnection.Password := password;
pgConnection.Database := Database;
pgConnection.Pooling := false;
pgQuery := TPgQuery.Create(nil);
pgQuery.Connection := pgConnection;
pgQuery.SQL.Text := 'select * from ' + TableName;
pgQuery.Open;
pgQuery.free;
pgConnection.free;
sleep(10);
end;

var
i: integer;
begin
try

writeLn('Starting...');

for i := 0 to 1000 do
begin
newTask( i );
sleep(10);
end;

writeLn('Freeing...');

except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

Comments

  1. Dalija Prasnikar Thanks! that is the kind of article I needed... I now completely understand why everyone keeps writing 'ARC' is terrible but I've found it hard to find a 'because' article. I think the huge problem with the design taken by EMB is that they make it 'appear' like your code is working and compiling fine on linux but in fact is suffering from massive memory leaks. Every component vendor has just compiled on Linux and as everything looked ok, then released as is without checking the detail. I'm sure many developers will do the same. I find it surprising there isn't a massive article titled 'DON'T COMPILE YOUR CODE TO LINUX UNTIL YOU READ THIS' because the idea of creating and free'ing an object, especially ones with a parent/child relationship is to fundamental to delphi object design and many of us would clean up child references in the destructor which is never called under ARC... hmmm

    ReplyDelete
  2. Keep in mind that calling DisposeOf will not break all strong reference cycles. Only the ones that are explicitly resolved in destructor (like TComponent FreeNotification system) handles things.

    For other reference cycles you may also need to mark non-owning references with [weak] or [unsafe] attribute. Typically in parent-child relationship you would want to mark parent reference in child as [weak] or [unsafe].

    ReplyDelete
  3. This is one of the technical reasons why we use FPC for compiling our source code to Linux, not Delphi...

    ReplyDelete

Post a Comment