Memory-allocation just keeps growing out of control! 
Author Message
 Memory-allocation just keeps growing out of control!

Help

I have - what I think - a normal piece of Delphi-code which uses database
access to a SQL-Server. I'm about to write a rutine to transfer data from
one (SQL-Server) database to another and it includes a lot of deleting data
(if it already exists) and appending data in the destination database

I also includes some "try - post - excepts" in case data shouldn't be
deleted first and then appended, but just throw an exception if there
already is a key in the table.

My problem is that when the program is running I can see the memory in the
task manager get eaten away and eventually the program halts with an
exception of some sort. Where is the "memory leak"? Help...

I'm a bit new to delphi and if I can't figure out how to solve this problem
I'll have to cook something up in Microsoft Access - and I really like not
to go down that path...

My consists of a lot of these procedures:

-----------------------------------------------------------------------
procedure TransferDataPortion
var
  DeleteQ : TQuery;
  Source : TQuery;
  Dest : TTable;
begin

  DeleteQ := TQuery.Create(nil);
  DeleteQ := DB2.DatabaseName;
  DeleteQ.SQL.Add('DELETE FROM Table1 WHERE SomeThing=SomeOtherThing');
  DeleteQ.ExecSQL;
  DeleteQ.Free;

  Source := TQuery.Create(nil);
  Source.DatabaseName:=DB1.Databasename;
  Source.SQL.Add('SELECT * FROM Table1 WHERE SomeThing=SomeOtherThing');
  Source.Open;

  Dest := TQuery.Create(nil);
  Dest.DatabaseName := DB2.Databasename;
  Dest.TableName := 'Table1';
  Dest.Open;

  While Not Source.EOF Do Begin
        Dest.Append;
        Dest.FieldByName(Something).AsSomething :=
Source.FieldByName(Something).AsSomething;
        Dest.FieldByName(Something).AsSomething :=
Source.FieldByName(Something).AsSomething;
        Dest.FieldByName(Something).AsSomething :=
Source.FieldByName(Something).AsSomething;
        Dest.FieldByName(Something).AsSomething :=
Source.FieldByName(Something).AsSomething;
        Dest.Post;
        Source.Next;
   End;

   Dest.Close;
   Dest.Free;
   Source.Close;
   Source.Free;
End;
-----------------------------------------------------------------------

And in the case that data just should be tried append:

-----------------------------------------------------------------------
procedure TransferDataPortion
var
  Source : TQuery;
  Dest : TTable;
begin

  Source := TQuery.Create(nil);
  Source.DatabaseName:=DB1.Databasename;
  Source.SQL.Add('SELECT * FROM Table1 WHERE SomeThing=SomeOtherThing');
  Source.Open;

  Dest := TQuery.Create(nil);
  Dest.DatabaseName := DB2.Databasename;
  Dest.TableName := 'Table1';
  Dest.Open;

  While Not Source.EOF Do Begin
        Dest.Append;
        Dest.FieldByName(Something).AsSomething :=
Source.FieldByName(Something).AsSomething;
        Dest.FieldByName(Something).AsSomething :=
Source.FieldByName(Something).AsSomething;
        Dest.FieldByName(Something).AsSomething :=
Source.FieldByName(Something).AsSomething;
        Dest.FieldByName(Something).AsSomething :=
Source.FieldByName(Something).AsSomething;
        Try
           Dest.Post;
        Except
           Dest.Cancel;
        End;
        Source.Next;
   End;

   Dest.Close;
   Dest.Free;
   Source.Close;
   Source.Free;
End;



Wed, 18 Jun 1902 08:00:00 GMT  
 Memory-allocation just keeps growing out of control!


Quote:
>I have - what I think - a normal piece of Delphi-code which uses database
>access to a SQL-Server. I'm about to write a rutine to transfer data from
>one (SQL-Server) database to another and it includes a lot of deleting data
>(if it already exists) and appending data in the destination database

>I also includes some "try - post - excepts" in case data shouldn't be
>deleted first and then appended, but just throw an exception if there
>already is a key in the table.

>My problem is that when the program is running I can see the memory in the
>task manager get eaten away and eventually the program halts with an
>exception of some sort. Where is the "memory leak"? Help...

Try using unidirectional queries:

Quote:
>  Source := TQuery.Create(nil);
>  Source.DatabaseName:=DB1.Databasename;
>  Source.SQL.Add('SELECT * FROM Table1 WHERE SomeThing=SomeOtherThing');

   Source.UniDirectional := true;

Quote:
>  Source.Open;

When a query is bidirectional, the BDE tries to cache all of the data it
reads from the query so that you can scroll backwards.  That can take a
lot of memory.  If you're only going to read forward, a unidirectional
query is much more efficient.

--
"Generally speaking, things have gone about as far as they can possibly
go when things have got about as bad as they reasonably get."



Wed, 18 Jun 1902 08:00:00 GMT  
 Memory-allocation just keeps growing out of control!
A good programming practice to avoid memory leak would be to protect your
memory allocations with try / finally block.: create constructors should
always have their associated frees within the corresponding finally block.

ie the code should look like this :
try
   Source := TQuery.Create(nil);
   Dest := TQuery.Create(nil);
   copy the database
finally
   Source.Close;
   Source.Free;
   Dest.Close;
   Dest.Free;
end

If you wish, you may even use two nested try / finally blocks, but I don't
think it is necessary in your case.

Hope it will help.

Good luck.

Emmanuel

for each

Quote:

>Help

>I have - what I think - a normal piece of Delphi-code which uses database
>access to a SQL-Server. I'm about to write a rutine to transfer data from
>one (SQL-Server) database to another and it includes a lot of deleting data
>(if it already exists) and appending data in the destination database

>I also includes some "try - post - excepts" in case data shouldn't be
>deleted first and then appended, but just throw an exception if there
>already is a key in the table.

>My problem is that when the program is running I can see the memory in the
>task manager get eaten away and eventually the program halts with an
>exception of some sort. Where is the "memory leak"? Help...

>I'm a bit new to Delphi and if I can't figure out how to solve this problem
>I'll have to cook something up in Microsoft Access - and I really like not
>to go down that path...

>My consists of a lot of these procedures:

>-----------------------------------------------------------------------
>procedure TransferDataPortion
>var
>  DeleteQ : TQuery;
>  Source : TQuery;
>  Dest : TTable;
>begin

>  DeleteQ := TQuery.Create(nil);
>  DeleteQ := DB2.DatabaseName;
>  DeleteQ.SQL.Add('DELETE FROM Table1 WHERE SomeThing=SomeOtherThing');
>  DeleteQ.ExecSQL;
>  DeleteQ.Free;

>  Source := TQuery.Create(nil);
>  Source.DatabaseName:=DB1.Databasename;
>  Source.SQL.Add('SELECT * FROM Table1 WHERE SomeThing=SomeOtherThing');
>  Source.Open;

>  Dest := TQuery.Create(nil);
>  Dest.DatabaseName := DB2.Databasename;
>  Dest.TableName := 'Table1';
>  Dest.Open;

>  While Not Source.EOF Do Begin
>        Dest.Append;
>        Dest.FieldByName(Something).AsSomething :=
>Source.FieldByName(Something).AsSomething;
>        Dest.FieldByName(Something).AsSomething :=
>Source.FieldByName(Something).AsSomething;
>        Dest.FieldByName(Something).AsSomething :=
>Source.FieldByName(Something).AsSomething;
>        Dest.FieldByName(Something).AsSomething :=
>Source.FieldByName(Something).AsSomething;
>        Dest.Post;
>        Source.Next;
>   End;

>   Dest.Close;
>   Dest.Free;
>   Source.Close;
>   Source.Free;
>End;
>-----------------------------------------------------------------------

>And in the case that data just should be tried append:

>-----------------------------------------------------------------------
>procedure TransferDataPortion
>var
>  Source : TQuery;
>  Dest : TTable;
>begin

>  Source := TQuery.Create(nil);
>  Source.DatabaseName:=DB1.Databasename;
>  Source.SQL.Add('SELECT * FROM Table1 WHERE SomeThing=SomeOtherThing');
>  Source.Open;

>  Dest := TQuery.Create(nil);
>  Dest.DatabaseName := DB2.Databasename;
>  Dest.TableName := 'Table1';
>  Dest.Open;

>  While Not Source.EOF Do Begin
>        Dest.Append;
>        Dest.FieldByName(Something).AsSomething :=
>Source.FieldByName(Something).AsSomething;
>        Dest.FieldByName(Something).AsSomething :=
>Source.FieldByName(Something).AsSomething;
>        Dest.FieldByName(Something).AsSomething :=
>Source.FieldByName(Something).AsSomething;
>        Dest.FieldByName(Something).AsSomething :=
>Source.FieldByName(Something).AsSomething;
>        Try
>           Dest.Post;
>        Except
>           Dest.Cancel;
>        End;
>        Source.Next;
>   End;

>   Dest.Close;
>   Dest.Free;
>   Source.Close;
>   Source.Free;
>End;



Wed, 18 Jun 1902 08:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. TechTips: Why does the file keep on growing?

2. dynamic allocation of memory - help with error

3. Real mode memory allocation and forced $0 offsets in BP7.0

4. Memory Allocation Errors (Simon Watkins)

5. Memory Allocation Sizes Directive and exec

6. BP7 DPMI memory allocation

7. Array access to large memory allocation

8. Array/Pointer memory allocation?

9. Memory allocation err, time measurment

10. memory allocation/comparison

11. Memory allocation under Win3.11

12. Large linear memory allocations

 

 
Powered by phpBB® Forum Software