Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.12.26;
Скачать: CL | DM;

Вниз

Утечка памяти в TADODataset.   Найти похожие ветки 

 
b@mboZe   (2004-11-26 12:07) [0]

Всем доброго времени суток.
У меня следующая задача: импортировать данные из excel файлов по списку (в списке >30 файлов) в MS SQL БД.
Возникла проблема: при занесении значений в TADODataset память, выделенная под них, не освобождается. Т.е. код типа
ADODataset.FieldValues["Field1"] := "String constant";
дает утечку памяти. Мне, конечно, не жалко одну строку, но проблема в том, таких строк в одном .xls от 3000-7000 умножить на количество файлов = весьма ощутимая утечка памяти.
Факт утечки проверял MemProof-ом. На нижеследующий пример Memproof в результатах (Resource Details) пишет
...
    1265  SysString             0017BDFC         16  SysAllocStringLen(Liking string #5,16)
    1271  SysString             0017BDFC         16  SysAllocStringLen(Liking string #6,16)
...
    7193  SysString             0017BDFC         18  SysAllocStringLen(Liking string #993,18)
    7199  SysString             0017BDFC         18  SysAllocStringLen(Liking string #994,18)
...
т.е. не была освобождена память на строки "Liking string #" c 1 по 1000. На закладке счетчиков ресурсов (Resource counters) он пишет:
Resources  Resource Count  Resource Size
Area Item  Current # Peak # Current Size Peak Size
...
COM CoInitialize 0  1 0   0
OLE SysString 1002   1008  17918   18395
GDI  Pen  0   1  0   0
...

Т.е. не освобождено 1002 строк, причем из OLE. Вопрос, по сути, относится скорее к COM ветке форума, однако, ИМХО, веротность найти ответ в этой ветке больше.
Может, кто-нибудь сталкивался с такой проблемой?

Вот пример кода, вызывающего утечку:
procedure TForm1.Button1Click(Sender: TObject);
var
 i: integer;
 Conn: TADOConnection;
 Comm: TADOCommand;
 ds: TADODataSet;
begin
 Conn := TADOConnection.Create(self);
 Conn.ConnectionString := "Provider=SQLOLEDB.1;Password=;Persist"
   + " Security Info=true;User ID=bamboze;Initial Catalog=DebitCredit;Data "
   + "Source=PHYSALIS\BAMMSSQL;"
   + "Workstation ID=PHYSALIS;";
 Conn.LoginPrompt := true;
 conn.Connected := true;

 Comm := TADOCommand.Create(self);
 Comm.Connection := Conn;
 Comm.CommandText := "if object_id(""T_TMP_TEST"") is not null drop table T_TMP_TEST create table T_TMP_TEST(id integer identity(1,1), Value varchar(255))";
 Comm.Execute;

 ds := TADODataSet.Create(self);
 ds.Connection := conn;
 ds.CommandType := cmdTable;
 ds.CommandText := "T_TMP_TEST";
 ds.Active := false;
 ds.Active := true;
 for i :=1 to 1000 do
 begin
   ds.Append;
   ds.FieldByName("Value").Value := "Liking string #" + IntToStr(i);
 end;
 ds.Free;
 comm.Free;
 conn.Free;
 ShowMessage("Done!");
end;


 
Johnmen ©   (2004-11-26 13:03) [1]

1. После второй строки тела цикла - ds.Post; (или 1 раз после цикла)
2. Перед разрушением соединения его надо разорвать.


 
b@mboZe   (2004-11-26 13:36) [2]

Johnmen ©   (26.11.04 13:03) [1]
Спасибо за замечания, однако утечку это не устранило :( . OLE по-прежнему не освобождает память строк.
Кстати: пробовал использовать TADOCommand ("insert T_TMP_TEST ...") вместо TADODataset, т.е. в цикле
ADOCommand.CommandText := "insert TPriceExcelPreImport values(""Liking string #"+ IntToStr(i)+""")";
ADOCommand.Execute;
Тоже не освобождается память! Просто на этот раз пишет, что не освобождена память, выделенная под строки "insert TPriceExcelPreImport values("Liking string #1")" и т.п.

Мастера, неужели никто не сталкивался с подобной проблемой/задачей? Какие есть альтернативные способы импортировать из excel в MS SQL ? (кроме DTS - их можно создать только на 1 конкретный excel-файл; и последовательности сохранить xls как txt, импортировать используя bcp.exe)


 
Johnmen ©   (2004-11-26 13:49) [3]

>b@mboZe

Посмотри, будет ли утечка (нарастание количества утёкшего), если
запустить-выйти, запустить-выйти, ...


 
b@mboZe ©   (2004-11-26 13:54) [4]

Проверял, не будет. Утечка возникает только если запускать импорт.


 
Johnmen ©   (2004-11-26 14:20) [5]

Вот я и имел в виду - запустить импорт-выйти, запустить импорт-выйти, ...


 
b@mboZe ©   (2004-11-26 14:57) [6]

Три раза подряд запустил импорт, результат: около 3000 неосвообжденных строк. Т.е. ADO выделяет пямять, использует, и забывает освободить.
В самом ADO проблемы могут быть?


 
Johnmen ©   (2004-11-26 15:18) [7]

А от сервера автоматизации Exel отсоединяешься ? А подсоединяешься как ? Сервер выгружаешь ?


 
b@mboZe ©   (2004-11-26 15:31) [8]

Ранним связыванием. Вот так заканчиваю сессию с excel:
if Assigned(ExcelApp) then
   begin
     ExcelApp.Workbooks[1].Close(false, EmptyParam, EmptyParam, xlLCID);
     ExcelApp.Workbooks.Close(xlLCID);
     ExcelApp.Quit;
     //FreeAndNil(Values);
     FreeAndNil(ExcelApp);
   end;
   if Assigned(ExcelWorkSheet1) then
     FreeAndNil(ExcelWorkSheet1);

Вот так начинаю сессию:
 ExcelApp := TExcelApplication.Create(self);
 ExcelWorksheet1 := TExcelWorksheet.Create(self);
 Result := false;
 ExcelApp.ConnectKind := ckNewInstance;
 ExcelApp.Connect;

 if Assigned(ExcelApp) then begin
   ExcelApp.Visible[xlLCID] := false;
   if ExcelApp.WindowState[xlLCID] = TOLEEnum(xlMinimized) then
     ExcelApp.WindowState[xlLCID] := TOLEEnum(xlNormal);
   ExcelApp.ScreenUpdating[xlLCID] := true;
 end;

 s:=filename;
 ExcelApp.Workbooks.Open(s, EmptyParam, EmptyParam,
   EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam,
   EmptyParam, EmptyParam, EmptyParam, EmptyParam, false, xlLCID);

 ExcelWorksheet1.ConnectTo( ExcelApp.ActiveSheet as _Worksheet);

 Values := ExcelWorksheet1.UsedRange[xlLCID].Value;
 iPLFieldsCount := VarArrayHighBound(Values, 2);

далее Values[i,j] считываю в TADOTable или TADOCommand



Страницы: 1 вся ветка

Текущий архив: 2004.12.26;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.023 c
14-1102020466
Marser
2004-12-02 23:47
2004.12.26
Хотелось бы узнать вашу точку зрения


14-1102412396
Dmitriy O.
2004-12-07 12:39
2004.12.26
Кто знает какие либо методы быстрого сброса данных В Эксель ?


14-1102494574
Rouse_
2004-12-08 11:29
2004.12.26
LOL


1-1102620522
SergP
2004-12-09 22:28
2004.12.26
Есть ли функции для преобразования строки в множество?


14-1102076441
easy
2004-12-03 15:20
2004.12.26
Alphablend