Форум: "Основная";
Текущий архив: 2004.12.26;
Скачать: [xml.tar.bz2];
ВнизУтечка памяти Найти похожие ветки
← →
maxz © (2004-12-14 18:34) [0]Hi2all!
В общем, у меня есть прога, в которой через определенные промежутки времени выполняется одна и та же процедура. после каждого такого выполнения теряется несколько килобайт оперативки. я полагаю, что неправильно работаю с указателями. подскажите, где ошибка?
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls,Registry;
type
TRegPart=(rpLM, rpCU);
TAutorunType=(atRun,atRunOnce,atRunOnceEx,atRunServices,atRunServicesOnce);
PStartupRec = ^AStartupRec;
AStartupRec=record
name: string;
command: string;
loadedfrom: string;
end;
type
TForm1 = class(TForm)
Timer1: TTimer;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
procedure CheckRunData(rp: TRegPart;AType: TAutorunType;var d: TList);
end;
const
RUN="Software\Microsoft\Windows\CurrentVersion\Run";
RUN_ONCE="Software\Microsoft\Windows\CurrentVersion\RunOnce";
RUN_ONCE_EX="Software\Microsoft\Windows\CurrentVersion\RunOnceEx";
RUN_SERVICES="Software\Microsoft\Windows\CurrentVersion\RunServices";
RUN_SERVICES_ONCE="Software\Microsoft\Windows\CurrentVersion\RunServicesOnce";
var
Form1: TForm1;
implementation
procedure TForm1.CheckRunData(rp: TRegPart;AType: TAutorunType;var d: TList);
var
hReg: TRegIniFile;
i: integer;
RegName,RegPath: string;
val: TStringList;
sd: PStartupRec;
begin
i:=0;
val:=TStringList.Create;
hReg:=TRegIniFile.Create;
if rp=rpCU then RegName:="HKCU\" else RegName:="HKLM\";
case AType of
atRun: begin
RegName:=RegName+"Run";
RegPath:=RUN;
end;
atRunOnce: begin
RegName:=RegName+"RunOnce";
RegPath:=RUN_ONCE;
end;
atRunOnceEx: begin
RegName:=RegName+"RunOnceEx";
RegPath:=RUN_ONCE_EX;
end;
atRunServices: begin
RegName:=RegName+"RunServices";
RegPath:=RUN_SERVICES;
end;
atRunServicesOnce: begin
RegName:=RegName+"RunServicesOnce";
RegPath:=RUN_SERVICES_ONCE;
end;
end;
with hReg do begin
case rp of
rpLM: RootKey:=HKEY_LOCAL_MACHINE;
rpCU: RootKey:=HKEY_CURRENT_USER;
end;
OpenKey(RegPath,false);
GetValueNames(val);
CloseKey;
end;
for i:=0 to (val.Count-1) do begin
New(sd);
sd^.name:=val[i];
sd^.command:=hReg.ReadString(RegPath,val[i],"");
sd^.loadedfrom:=RegName;
d.Add(sd);
end;
val.Clear;
val.Free;
hReg.Free;
end;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Close;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
d: TList;
i: integer;
begin
d:=TList.Create;
for i:=0 to 10 do CheckRunData(rpCU,atRun,d);
for i:=0 to d.Count-1 do dispose(d[i]);
d.Free;
end;
end.
← →
DiamondShark © (2004-12-14 18:48) [1]Вот здесь теряется:
> for i:=0 to d.Count-1 do dispose(d[i]);
А вот так не теряется:
for i:=0 to d.Count-1 do dispose(PStartupRec(d[i]));
← →
TUser © (2004-12-14 19:01) [2]1. Cоздание-уничтожение объектов надо писать в try..finally
2. Как часто выполняется эта процедура? Может ли быть такое, что очередное время Х наступит до того, как завершилась работа предыдущей итерации?
PS. Вот этот кусок можно существенно оптимизировать с помощью uses TypInfpo и массивов.> case AType of
> atRun: begin
> RegName:=RegName+"Run";
> RegPath:=RUN;
> end;
> atRunOnce: begin
> RegName:=RegName+"RunOnce";
> RegPath:=RUN_ONCE;
> end;
> atRunOnceEx: begin
> RegName:=RegName+"RunOnceEx";
> RegPath:=RUN_ONCE_EX;
> end;
> atRunServices: begin
> RegName:=RegName+"RunServices";
> RegPath:=RUN_SERVICES;
> end;
> atRunServicesOnce: begin
> RegName:=RegName+"RunServicesOnce";
> RegPath:=RUN_SERVICES_ONCE;
> end;
> end;
← →
TUser © (2004-12-14 19:10) [3]
> А вот так не теряется:
>
> for i:=0 to d.Count-1 do dispose(PStartupRec(d[i]));
А можете объяснить - почему, если сделать не через TList, а в виде связного списка, то никаких утечек не будет? А с TList"ом - действительно утечки. Например,PMine = ^TMine;
TMine =
record
S1: string;
S2: string;
Next: PMine;
end;
var
Form1: TForm1;
implementation
const
C = 10000;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var p,po:PMine;
i:integer;
begin
po:=nil;
for i:=0 to C-1 do begin
New(p);
p^.Next:=po;
po:=p;
p^.S1:="ANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXT";
p^.S2:="ANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXTANY TEXT";
end;
showmessage("!");
while p <> nil do begin
po:=p^.Next;
Dispose(p);
p:=po;
end;
end;
← →
Суслик © (2004-12-14 19:18) [4]
> А можете объяснить
потому, что для типизированных указателей dispose сначала вызывает finalize, что приводит к очистке значений с управляемым временем жизни (например, длинные строки), а для нетипизированных dispose при компиляции заменяется на freemem, который просто освобождает кусок памяти, не заботясь о освобождении содержимого.
← →
DiamondShark © (2004-12-14 19:44) [5]
> Вот этот кусок можно существенно оптимизировать с помощью
> uses TypInfpo и массивов.
Оно и без uses неплохо получится:
const
RunConst = "Software\Microsoft\Windows\CurrentVersion\";
Runs: array[TAutoRunType] of string = (
"Run",
"RunOnce",
"RunOnceEx",
"RunServices",
"RunServicesOnce");
...
RegPath := RunConst + Runs[AType];
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.12.26;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.047 c