AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi *.Free aufgerufen, aber Speicher bleibt belegt?
Thema durchsuchen
Ansicht
Themen-Optionen

*.Free aufgerufen, aber Speicher bleibt belegt?

Ein Thema von Bloodfire · begonnen am 28. Mai 2005 · letzter Beitrag vom 28. Mai 2005
Antwort Antwort
Bloodfire

Registriert seit: 17. Jun 2004
38 Beiträge
 
#1

*.Free aufgerufen, aber Speicher bleibt belegt?

  Alt 28. Mai 2005, 13:12
Hi!

Zum besseren Verständis kruz die Vorgeschichte:
Das Programm soll ein Netzwerkschach werden, das aus einer Hauptform mit Userliste besteht, über die je Benutzer ein (aber maximal 5 insgesamt) Schachbrett aufgerufen wird.

Die Klasse des Schachbrettes ist ein TObject, welche eine Form beinhaltet und in etwa so aufgebaut ist:

Delphi-Quellcode:
  TChessBoard = class(TObject)
    ChessboardForm: TForm;
  private
    (...)
  public
    FormClosed: Boolean;

    constructor Create;
    destructor Destroy;override;
    (...)
Im Konstruktor wird nur die Form mit dem Owner 'nil' erzeugt und demnach auch in Destroy wieder freigegeben. Der Owner aller anderen kreierten Objekte ist die Form. (so müsste ich mich ja eigentlich nicht mehr um deren Löschung kümmern, oder?)

Delphi-Quellcode:
constructor TChessBoard.Create;
var
 i: Integer;
 TempOwner: TComponent;
begin
   //Formular
   ChessboardForm:=TForm.Create(nil);
   TempOwner:=ChessboardForm;

   //Menü
   MainMenu:=TMainMenu.Create(TempOwner);

   for i:=0 to MenuItemCount do
     MenuItem[i]:=TMenuItem.Create(MainMenu);

   //BoardPanel & Board
   BoardPanel:=TPanel.Create(TempOwner);
   Board:=TImage.Create(TempOwner);
   (...)
end;


destructor TChessBoard.Destroy;
begin
  ChessboardForm.Free;
  inherited;
end;
Da ich nun bei OnFormClose nicht die Klasse TChessboard befreien kann, setze ich die Variable FormClosed einfach auf True. Der Aufruf der einzelnen Schachbretter im Hauptprogramm sieht dann folgendermaßen aus:

Delphi-Quellcode:
procedure TMainAppSingle.OpenChess(FName: String; FLeft, FTop, FWidth,
  FHeight: Integer; FPathFigures, FExtFigures, FPathGraphics, FExtGraphics,
  FPathFiles: String; FBoardIndex: Integer);
var
  i: Integer;
  AMsg: String;
begin
   //Überprüfen, ob laufendes Chessboard schon geschlossen wurde
   for i:=1 to MaxChess do
     if not(ChessFree[i]) then
       if (ChessBoard[i].FormClosed) then
         begin
            ChessBoard[i].Free;
            ChessFree[i]:=True;
            dec(RunningChess);
         end;

   //Überprüfen, ob Schach mit diesem User schon läuft
   for i:=1 to MaxChess do
     if not(ChessFree[i]) then
       if ChessBoard[i].ChessboardForm.Caption=FName then
         begin
            ChessBoard[i].ChessboardForm.BringToFront;
            exit;
         end;

   //Überprüfen, ob Maximalanzahl an Schachbretterb initialisiert wurden
   if (RunningChess>=MaxChess) then
     begin
        AMsg:=SysCommands.ReadCaption('MainApp','MaxChess')+
          ' ('+IntToStr(MaxChess)+')';
        MessageDlg(AMsg,mtInformation,[mbOk],0);
        exit;
     end;


   //Neues Spiel initialisieren:

   inc(RunningChess);

   i:=1;
   while (not(ChessFree[i]))
     do inc(i);

   ChessFree[i]:=False;
   ChessBoard[i]:=TChessBoard.Create;
   ChessBoard[i].Init(nil,FName,FLeft,FTop,FWidth,FHeight,
     FPathFigures,FExtFigures,FPathGraphics,FExtGraphics,FPathFiles,
     FBoardIndex);
end;
(zur Info: die Parameter für die Netzwerkübertragung sind noch ausständig)

Essentielles Kurz zusammengefasst:
Ich überprüfe, ob eines der vormals geöffneten Schachfenster geschlossen wurde (die Klasse aber noch existiert) und befreie diese dann vom Speicher, was eigentlich bedeuten müsste:

Wenn ich zum Beispiel 2 Schachbretter aufmache und eines davon wieder schließe liegt der Speicherbedarf immernoch gleich. Wenn ich jedoch nun ein neues öffne, sollte der gleichbleiben, da ja die im untergrund noch existierende Klasse gelöscht, und die neue initielisiert wird, aber laut Taskmanager, nimmt der Bedarf an Speicher nur zu und ab etwa dem 10. Spielaufruf wird das auch an der Performance sichtbar.

Wo liegt hier der Fehler? Vergesse ich etwas zu befreien? Oder funktioniert das grundsätzlich anders!?
  Mit Zitat antworten Zitat
Phistev
(Gast)

n/a Beiträge
 
#2

Re: *.Free aufgerufen, aber Speicher bleibt belegt?

  Alt 28. Mai 2005, 13:28
Erstell mal ein eigenes Form (statt TForm) mit Hilfe des Formulardesigners. Evtl. muss intern eine Variable anders gesetzt werden. Alternativ gib die Komponenten selber frei (mittels TForm.Controls).
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: *.Free aufgerufen, aber Speicher bleibt belegt?

  Alt 28. Mai 2005, 13:33
Moin Bloodfire,

prüfe Dein Programm am besten mal mit MemProof, bzw. MemCheck.

Aussderdem könntest Du Dein Hauptprogramm vermutlichen vereinfachen, wenn Du Dir noch eine Klasse für die Liste der Formulare erstellst, und dort diese die Verwaltung übernimmt (Stichwort: TObjectList).
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:48 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