Форум: "Базы";
Текущий архив: 2002.03.25;
Скачать: [xml.tar.bz2];
ВнизTQuery.Prepare, сильные утечки памяти Найти похожие ветки
← →
Antony (2002-02-27 12:14) [0]Привет, коллеги.
Нарыл очень неприятную хезу, связанную с Query.Prepare
Суть:
1)Есть некий параметризованный запрос
2)Делаю Prepare этого запроса - в самом начале работы
3)Работаю с запросом
3.1)устанавливаю параметр
3.2)делаю Open
3.3)читаю данные
3.4)делаю Close
4) В конце работы программы делаю UnPrepare
к пункту 3) в процессе работы обращаюсь некоторое, - достаточно большое,
колличество раз. После каждого прохода по 3) сильно растёт память(буквально
сотнями килобайт) и после Close не освобождается. Итого выходит что за день
работы у меня утекает порядка 70 Мегабайт, - удручающий показатель.
Самое интересное что даже в конце после UnPrepare память не освобождается,
и даже после Disconnect не освобождается.
Вот.
Если же не делать Prepare/UnPrepare то всё впорядке, память не растёт, и
всё внорме, кроме одного! - производительность выполнения запросов падает
на 25%,
это согласитесь не так уж и мало.
Перерыл доку по BDE - никаких объяснений не нашел, перерыл все настройки
BDE - тоже ничего не помогает. Работаю я с восьмым ораклом - но сомнительно
всё же чтобы это было как-то связано с ораклом.
Может быть кто-нибудь знает в чём тут дело и как это можно пофиксить?
Да, своих утечек нет, всё протестировал. Да вобщем-то потом просто написал
тестик который наглядно демонстрирует данную проблему:
unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, datas;
type
TMainForm = class(TForm)
OutPut: TMemo;
PRFButton: TButton;
Button1: TButton;
Button2: TButton;
procedure PRFButtonClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
switch:boolean;
count:integer;
procedure HeepStatusSpool(Caption:String);
public
{ Public declarations }
end;
var
MainForm: TMainForm;
implementation
uses ShareMem;
{$R *.DFM}
procedure TMainForm.HeepStatusSpool(Caption:String);
var
HeapStatus:THeapStatus;
begin
HeapStatus:=ShareMem.GetHeapStatus();
with OutPut.Lines do
begin
Add("");
Add(Caption);
Add("---------------------------------------------------");
Add("TotalAllocated : "+IntToStr(HeapStatus.TotalAllocated));
Add("TotalFree : "+IntToStr(HeapStatus.TotalFree));
Add("TotalCommitted : "+IntToStr(HeapStatus.TotalCommitted));
Add("TotalUnCommitted : "+IntToStr(HeapStatus.TotalUnCommitted));
Add("TotalAddrSpace : "+IntToStr(HeapStatus.TotalAddrSpace));
Add("Overhead : "+IntToStr(HeapStatus.Overhead));
Add("Unused : "+IntToStr(HeapStatus.Unused));
Add("HeapErrorCode : "+IntToStr(HeapStatus.HeapErrorCode));
Add("===================================================");
Add("AllocMemCount : "+IntToStr(GetAllocMemCount()));
Add("AllocMemSize : "+IntToStr(GetAllocMemSize()));
Add("---------------------------------------------------");
end;
end;
procedure TMainForm.PRFButtonClick(Sender: TObject);
var
ST, FT:integer;
counter:integer;
begin
ST:=GetTickCount();
HeepStatusSpool("Start. GTC = "+IntToStr(ST));
for counter:=0 to count do
begin
switch:=not switch;
if switch then
DMP.PRQuery.ParamByName("TT").asString:="TABLE"
else
DMP.PRQuery.ParamByName("TT").asString:="VIEW";
DMP.PRQuery.Open;
while not DMP.PRQuery.Eof do DMP.PRQuery.Next;
DMP.PRQuery.Close;
end;
FT:=GetTickCount();
HeepStatusSpool("Start. GTC = "+IntToStr(FT)+" MUL = "+IntToStr(FT-ST));
end;
procedure TMainForm.Button1Click(Sender: TObject);
begin
DMP.PRQuery.Active:=False;
DMP.PRQuery.Prepare;
end;
procedure TMainForm.Button2Click(Sender: TObject);
begin
DMP.PRQuery.Active:=False;
DMP.PRQuery.UnPrepare;
end;
procedure TMainForm.FormCreate(Sender: TObject);
begin
switch:=true;
count:=1000;
end;
end.
_________________________________________________
В проекте должен быть дата модуль с названием DMP:TDataModule; в дата модуле
TSession TDataBase и запрос PRQuery [select TABLE_NAME from cat where TABLE_TYPE
= :TT]
на форме MainForm:TMainForm - три кнопки и OutPut:TMemo
запускаем TaskManager и наслаждаемся пейзажем :-))
Если будете юзать примерчик, то в проекте первым юнитом, должен быть воткнут ShareMem чтобы можно было пользоваться функциями
GetAllocMemCount();
GetAllocMemSize();
------------------------------------------------------------------------------------
program qp;
uses
ShareMem,
Forms,
main in "main.pas" {MainForm},
datas in "datas.pas" {DMP: TDataModule};
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.CreateForm(TDMP, DMP);
Application.Run;
end.
← →
roottim (2002-02-27 12:55) [1]а ты не пробовал не в конце программы а после каждого закрытия вызывать метод UnPrepare!...
помоему они должны работать всегда в паре
как Open .. Close
так и Prepare .. UnPrepare
← →
Antony (2002-02-27 13:43) [2]если так делать то пропадает всякий смысл в Prepare/UnPrepare
но понятно, что так всё нормально работает, только ещё дольше чем если бы я просто сделал Open/Close, такие пироги.
← →
roottim (2002-02-27 13:57) [3]я так думаю смысл всего этого оптимизировать закачку большого НД... а не в скорости при открытии и закрытии НД
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.03.25;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.004 c