So, I changed the cycle to this:
Code: Select all
While Not query.Eof Do
query.Next;
Just like this, cycling through 27.000 LOBs increased the memory usage of my application from 60 MB to 211 MB. Without accessing any LOBs whatsoever.
So, the increased memory is not coming from LOBs not being released, but the descriptions (TZOracleClob Delphi object?) not being freed when cursor position changes. I did the test by standing on the same commit, before the LobCacheMode change - but as not the LOBs are the problem it seems to be irrelevant.
Edit: Yes, that is going to be the issue. Changing the query from SELECT ID, CLOBFIELD to SELECT ID and cycling through the same 27.000 records my application stays on ~30 MB of memory usage.
Edit-edit: the object gets created at ZDbcCache : 1315 (TZRowAccessor.FillFromFromResultSet.InternalSetLob)
Code: Select all
PIZLob(Dest)^ := ResultSet.GetBlob(ResultSetIndex);
which is called from ZDbcCache :1378 (TZRowAccessor.FillFromFromResultSet)
Code: Select all
stAsciiStream, stUnicodeStream, stBinaryStream: InternalSetLob(PIZLob(Data), ResultSet, ResultsetIndex);
Data is a pointer, calculated like...
Code: Select all
P := @FBuffer.Columns[FColumnOffsets[ColumnIndex]];
{$IFDEF RangeCheckEnabled}{$R+}{$ENDIF}
Data := Pointer(PAnsiChar(P)+1);
I think this should be freed up too if we are not caching LOBs, no?