Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TObjectList - Objekte löschen, speicher freigeben??? (https://www.delphipraxis.net/121565-tobjectlist-objekte-loeschen-speicher-freigeben.html)

romber 30. Sep 2008 13:01


TObjectList - Objekte löschen, speicher freigeben???
 
Hallo!

Ich habe eine eine neue Klasse erstellt mit einer TObjectList drin, in die mehrere Instanzen einer anderen Klasse hinzufügt werden. Nun möchte ich es so machen, wenn ein Item aus TObjectList gelöscht wird, soll auch das eigentliche Objekt freigegeben werden. Bei mir ist es leider nicht der Fall. Ich füge 10000 Objekte hinzu und beobachte im Windows Taskmanager, wie viel Arbeitsspeicher verwendet wird. Wenn ich dann die Liste mit Clear sauber mache, bleibt die Höhe des verwendeten Arbeitsspeicher fast unverändert, als ob dir Objekte alle noch da währen. Die Eingeschaft OwnsObjects der TObjectList ist auf true gesetzt. Warum ist es so, was mache ich falsch?

Delphi-Quellcode:
type
  TImmObject = class(TObject)
  private
    FStatus: integer;
    FTyp: integer;
  public
    constructor Create;
    destructor Destroy; override;

    property Status: integer read FStatus write FStatus;
    property Typ: integer read FTyp write FTyp;
end;

type
  TImmObjects = class(TComponent)
  private
    FImmObjects: TObjectList;
  protected
    function GetImmObject(Index: Integer): TImmObject;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    function Count: integer;
    property ImmObject[Index: integer]: TImmObject read GetImmObject;
    property ImmObjects: TObjectList read FImmObjects write FImmObjects;
    procedure Clear;
end;

...

var
  Wohnungen: TImmObjects;

...

constructor TImmObject.Create;
begin
  inherited Create;
end;

destructor TImmObject.Destroy;
begin
  inherited Destroy;
end;

...

constructor TImmObjects.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FImmObjects := TObjectList.Create(true);
end;

destructor TImmObjects.Destroy;
begin
  FImmObjects.Free;
  inherited Destroy;
end;

function TImmObjects.GetImmObject(Index: Integer): TImmObject;
begin
  Result := (FImmObjects.Items[Index] as TImmObject);
end;

function TImmObjects.Count: integer;
begin
  Result := FImmObjects.Count;
end;

procedure TImmObjects.Clear;
begin
  FImmObjects.Clear;
end;

...

{Die Liste wird erstellt}
procedure TForm1.FormCreate(Sender: TObject);
begin
  Wohnungen := TImmObjects.Create(nil);
end;

{Hier werden die Objekte hinzufügt}
procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
  Wohnung: TImmObject;
begin
  for i := 0 to 100000 do
  begin
    Wohnung := TImmObject.Create;
    Wohnungen.ImmObjects.Add(Wohnung);
  end;
end;

{Hier wird die Liste gelehrt}
procedure TForm1.Button2Click(Sender: TObject);
begin
  Wohnungen.Clear;
end;

sirius 30. Sep 2008 13:03

Re: TObjectList - Objekte löschen, speicher freigeben???
 
Nix machst du falsch. Zwischen deinem Code und Windows hängt noch der Speichermanager von Delphi. Und der gibt so schnell den Speicher nicht an Windows zurück.
==> Der Taskmanager ist kein Maß für den aktuellen Speicherverbrauch deines Codes.

Edit:
Schau dir mal die Funktion GetHeapStatus an!

romber 30. Sep 2008 17:47

Re: TObjectList - Objekte löschen, speicher freigeben???
 
Das ist schön. Aber auch wenn ich die Datei ausserhalb Delphi-IDE ausführe, zeigt Windows Taskmanager das gleiche Speicherverbrauch.

jfheins 30. Sep 2008 17:53

Re: TObjectList - Objekte löschen, speicher freigeben???
 
Der Delphi-Speichermanager ist auch in deiner Anwendung, und nicht in der IDE :roll:

Deine Anwendung ist ja (wahrscheinlich) mit Delphi programmiert, und damit nicht jeedesmal, wenn du Speicher anforderst etwas von Windowas angefordert wird (langsam) hat deine Anwendung einen Speichermanager. Der sorgt dafür, dass wenn Speicher freigegeben wird, dieser (erstmal) nicht an Windows zurückgegeben wird. Wenn du jetzt erneutt Speicher brauchst, kann auf diesen Puffer zurückgegriffen werden.

Mach mal folgendes:

erstelle die 100000 Objekte
gib alle wieder frei
erstelle sie erneut
gib alle wieder frei
erstelle sie erneut

Wenn währenddessen der Speicherverbrauch signifikant steigt, dann werden sie tatsächlich nicht korrekt freigegeben. Ansonsten (Speicherverbrauch konstant) brtauchst du dir keine Sorgen machen ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:46 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz