Утечка памяти в Delphi XE3 при возникновении ошибки при вставке в БД sqlite
...
Query: TSQLQuery
...
Query.SQL.Clear;
Query.SQL.Add('INSERT INTO pumps'#13#10 +
'VALUES (NULL, :title, :power)');
Query.ParamByName('title').AsString:= title;
Query.ParamByName('power').AsFloat:= power;
try
Query.ExecSQL;
except
on E: Exception do
begin
ShowMessage(E.Message);
end;
end;
Запрос связан с SQLConnection с драйвером=Sqlite. Все операции работают, но когда я пытаюсь вставить неуникальное значение в столбец с уникальным индексом,я получаю исключение о существовании значения. Хорошо, мой код ловит его и показывает сообщение "заголовок столбца не уникален", но прежде отладчик показывает мне это исключение дважды. Когда я закрываю программу, диспетчер памяти сообщает об утечках памяти, и эти утечки являются:
- 21-28 байт: UnicodeString x 4
- 61-68 байт: TDBXSqliteCommand x2
- 221-236 байт: неизвестно x 2
[5]}69-76 байт: TDBXMorphicCommand x 2
Можно ли этого избежать?
UPD: я использовал FastMM4 для получения подробного журнала, и ниже приведена часть об одной утечке памяти:
A memory block has been leaked. The size is: 68
This block was allocated by thread 0xB18, and the stack trace (return addresses) at the time was:
4068A6 [System.pas][System][@GetMem$qqri][4203]
4082BB [System.pas][System][TObject.NewInstance$qqrv][14969]
4089D2 [System.pas][System][@ClassCreate$qqrpvzc][16231]
7D5A91 [Data.DbxSqlite.pas][Data.DbxSqlite][Dbxsqlite.TDBXSqliteCommand.$bctr$qqrp26Data.Dbxcommon.TDBXContextp35Data.Dbxsqlite.TDBXSqliteConnection][567]
6E3DFE [Data.DBXCommon][Generics.Collections.%TDictionary__2$20System.UnicodeStringp32Data.Dbxcommon.TDBXCreateCommand%.GetBucketIndex$qqrx20System.UnicodeStringi]
7D4C8E [Data.DbxSqlite.pas][Data.DbxSqlite][Dbxsqlite.TDBXSqliteDriver.CreateSqliteCommand$qqrp26Data.Dbxcommon.TDBXContextp29Data.Dbxcommon.TDBXConnectionp26Data.Dbxcommon.TDBXCommand][295]
6CE4DA [Data.DBXCommon.pas][Data.DBXCommon][Dbxcommon.TDBXDriver.CreateMorphCommand$qqrp26Data.Dbxcommon.TDBXContextp29Data.Dbxcommon.TDBXConnectionp26Data.Dbxcommon.TDBXCommand][7569]
6D5177 [Data.DBXCommon.pas][Data.DBXCommon][Dbxcommon.TDBXDelegateDriver.CreateMorphCommand$qqrp26Data.Dbxcommon.TDBXContextp29Data.Dbxcommon.TDBXConnectionp26Data.Dbxcommon.TDBXCommand][11061]
6D09F4 [Data.DBXCommon.pas][Data.DBXCommon][Dbxcommon.TDBXConnection.CreateMorphCommand$qqrp26Data.Dbxcommon.TDBXCommand][8480]
6D1C21 [Data.DBXCommon.pas][Data.DBXCommon][Dbxcommon.TDBXMorphicCommand.DerivedOpen$qqrv][9084]
6D1974 [Data.DBXCommon.pas][Data.DBXCommon][Dbxcommon.TDBXCommand.Open$qqrv][8962]
The block is currently used for an object of class: TDBXSqliteCommand
1 ответ:
Я запускаю тесты с dbXpress SQLite и MySQL driver (XE3), и ваш код просто утекает с SQLite (также получите двойное исключение в режиме отладки), но это не делает с MySQL.
IMHO это ошибка, о которой следует сообщить QC.
Трассировка стека при первом возникновении исключения в отладчике
:769cc41f KERNELBASE.RaiseException + 0x58 Data.DBXCommon.TDBXContext.Error(???,'column title is not unique') Data.DbxSqlite.CheckError(19,???,$2F12738) Data.DbxSqlite.TDBXSqliteCommand.DerivedExecuteQuery Data.DBXCommon.TDBXCommand.ExecuteQuery Data.DBXCommon.TDBXMorphicCommand.ExecuteQuery Data.SqlExpr.TCustomSQLDataSet.ExecuteStatement Data.SqlExpr.TCustomSQLDataSet.ExecSQL(???) Data.SqlExpr.TSQLQuery.ExecSQL(???) Main_ViewU.TForm1.RunQuery($2E7B870,'Title',10) Main_ViewU.TForm1.Button1Click($2E85AD0)Трассировка стека при втором возникновении исключения в отладчике
:769cc41f KERNELBASE.RaiseException + 0x58 // <-- Exception interrupts Destroy Data.DBXCommon.TDBXContext.Error(???,'column title is not unique') Data.DbxSqlite.CheckError(19,???,$2F12738) Data.DbxSqlite.TDBXSqliteCommand.DerivedClose Data.DBXCommon.TDBXCommand.Close Data.DBXCommon.TDBXMorphicCommand.DerivedClose Data.DBXCommon.TDBXCommand.Close Data.DBXCommon.TDBXCommand.Destroy // <-- DESTROY Data.DBXCommon.TDBXMorphicCommand.Destroy // <-- DESTROY System.TObject.Free Data.SqlExpr.TCustomSQLDataSet.CloseStatement Data.SqlExpr.TCustomSQLDataSet.InternalFreeCommand Data.SqlExpr.TCustomSQLDataSet.FreeCommand Data.SqlExpr.TCustomSQLDataSet.ExecSQL(???) Data.SqlExpr.TSQLQuery.ExecSQL(???) Main_ViewU.TForm1.RunQuery($2E7B870,'Title',10) Main_ViewU.TForm1.Button1Click($2E85AD0)И это вызывает утечку памяти ...
Comments