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

Вниз

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

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

Наверх




Память: 0.49 MB
Время: 0.031 c
1-1102685680
malij
2004-12-10 16:34
2004.12.26
поиск


3-1101135567
Sid
2004-11-22 17:59
2004.12.26
QReport???


1-1103101701
Руслана
2004-12-15 12:08
2004.12.26
Скажите как изменить цвет строки в ListView?


14-1101833468
OneFragLeft
2004-11-30 19:51
2004.12.26
Счастливые трусов не надевают...


1-1102600798
гость
2004-12-09 16:59
2004.12.26
Как вытащить иконку из окна если есть его хендл?