Jeff Overcash (TeamB)
Re: IBQuery memory leak

Re: IBQuery memory leak

Jeff Overcash (TeamB) wrote:
> Charles Jensen wrote:
>> I'm having a problem with memory leaks after updating (several) projects from XE2 to XE3.
>> Clearly visible when ReportMemoryLeaksOnShutdown is enabled. => It seems to be related to using TIBQuery. 
>> Could it be because memory is allocated with GetMem/ReAllocMem (in IBAlloc) and freed by "FreeRecordBuffer" by setting the pointer to nil?
>> - Charles
> Yes that is a leak.  change it to
> procedure TIBCustomDataSet.FreeRecordBuffer(var Buffer: TRecordBuffer);
> begin
>    if Assigned(Buffer) then
>      ReallocMem(Buffer, 0);
> end;
> and statically link IBCustomDataset.pas to your app (Might need IBQuery.pas too).
> For most of XE3's beta TRecordBuffer at the db.pas level was defined as 
> Array<byte> so was allocated with SetLength and deallocated with setting it to 
> nil.  Very late in the beta it was switched back to a pointer and this line was 
> missed (Actually someone on the dev team switched it back for me and I just 
> verified changes, this didn't change cause they missed it so I didn't catch it 
> either, still my fault).

found two more going through the code.  Also change

destructor TIBCustomDataSet.Destroy; begin
   Close;    FreeAndNil(FDataLink);    FreeAndNil(FBase);    ClearBlobCache;    FreeAndNil(FBlobStreamList);    FreeMem(FBufferCache, 0);    FreeAndNil(FGeneratorField);    FreeMem(FOldBufferCache, 0);    FCacheSize := 0;    FOldCacheSize := 0;    FMappedFieldPosition := nil;
   inherited Destroy; end;
procedure TIBCustomDataSet.InternalClose; begin    if Assigned(Transaction) then      Transaction.CheckAutoStop;
   {note - to not raise an exception if the conenction is lost            before destroying the object, only close it if it is            not being destroyed. If it is being destroyed the            IBSQL will be cleaned up normally when it is destroyed}    if not (csDestroying in ComponentState) then      FQSelect.Close;    ClearBlobCache;
   FreeRecordBuffer(FModelBuffer);    FreeRecordBuffer(FOldBuffer);    FreeRecordBuffer(FTempBuffer);    FCurrentRecord := -1;    FOpen := False;    FRecordCount := 0;    FDeletedRecords := 0;    FRecordSize := 0;    FBPos := 0;    FOBPos := 0;    FCacheSize := 0;    FOldCacheSize := 0;    FBEnd := 0;    FOBEnd := 0;    if Assigned(FBufferCache) then      ReallocMem(FBufferCache, 0);    if Assigned(FOldBufferCache) then      ReallocMem(FOldBufferCache, 0);
   FUpdatesPending := false;    if not (csDestroying in ComponentState) then    begin      BindFields(False);
     if DefaultFields then        DestroyFields;    end; end;

-- Jeff Overcash (TeamB)        (Please do not email me directly unless asked. Thank You) And so I patrol in the valley of the shadow of the tricolor I must fear evil. For I am but mortal and mortals can only die. Asking questions, pleading answers from the nameless faceless watchers that stalk the carpeted corridors of Whitehall.               (Fish)
FYI: Phrase searches are enclosed in either single or double quotes
Originally created by
Tue, 13 Apr 2021 16:13:47 UTC
Copyright © 2009-2021
HREF Tools Corp.