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

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.013 c
3-80410
EAlexander
2002-02-26 12:56
2002.03.25
DOA & FastReport


3-80386
ava
2002-02-25 23:05
2002.03.25
В чем ошибка


1-80478
Донской
2002-03-12 10:53
2002.03.25
WORD_Delphi


14-80672
Merlin
2002-02-08 11:37
2002.03.25
Новая задачка


1-80602
Starkom
2002-03-11 13:34
2002.03.25
Проблема с TStringList.Duplicates в ЛистБоксе