Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Memory Leaks beheben (https://www.delphipraxis.net/156885-memory-leaks-beheben.html)

w4rheart 18. Dez 2010 22:11

Memory Leaks beheben
 
Hallo zusammen!

Bei meinem Programm treten andauernd memory leaks auf, und das nicht zu knapp :D
Hatte schon eine Auslastung von >500mb.

Das heisst also, dass irgendwo ziemlich schlecht programmiert wurde :roll:
Allerdings weiss ich nicht genau wo bzw. was das Problem ist.
Das Programm ist auch nich gerade klein (über 15 Units) und benutzt unter anderem auch noch Andorra 2d.

Wie behebt man soetwas?
Ich hab schon gegoogelt und Programme gesucht die mir das anzeigen, allerdings hilft mir das auch nicht wirklich weiter.

Gibt es für Delphi nicht evtl. so eine Art Addon eines Garbage Collectors wie bei C?

Meine Fragen sind evtl. etwas übergreifender, und nicht mal eben zu erklären, aber vll. hat jemand Links oder Ähnliches die mir weiterhelfen könnten? (Auf einem niedrigen Niveau bitte, bin kein Profi wie Ihr hier.. eher das Gegenteil... :lol:)
Wäre nett =)

MfG

xZise 18. Dez 2010 22:15

AW: Memory Leaks beheben
 
Du solltest erstmal Delphi-Referenz durchsuchenReportMemoryLeaksOnShutdown auf true setzen.

Dann kannst du eventuell schon eher einschätzen, was zum Problem werden könnte.

MfG
Fabian

w4rheart 18. Dez 2010 22:20

AW: Memory Leaks beheben
 
wenn ich in From1.Create ReportMemoryLeaksOnShutdown:=true setze kommt da undefinierter bezeichner.
welche unit muss ich dafür einbinden?

Deep-Sea 18. Dez 2010 22:49

AW: Memory Leaks beheben
 
Keine, da es in der implizit eingebunden Unit System definiert ist. Aber eben erst bei neueren Delphi-Versionen.

w4rheart 18. Dez 2010 22:52

AW: Memory Leaks beheben
 
hab delphi 7
wenn ich System enbinden will kommt Bezeichner redefiniert.
und nu?

Deep-Sea 18. Dez 2010 23:03

AW: Memory Leaks beheben
 
Ich sagte ja, System ist implizit eingebunden. Selbst wenn du die ganze Uses-Klausel entfernst, System wäre trotzdem eingebunden :wink:

Ich glaube FastMM wäre eine Möglichkeit. Bin da aber nicht gerade der beste Ansprechpartner für. Such doch einfach mal hier im Forum z.B. nach "Speicherleck" ...

stahli 18. Dez 2010 23:22

AW: Memory Leaks beheben
 
Suche mal in der DP nach "FastMM4" und "Optionen".
In der Ini von FastMM4 kannst Du einstellen, dass Dir eine komplexe Report-Datei erzeugt wird.

Habe es aber jetzt nicht im Detail parat...

w4rheart 19. Dez 2010 00:17

AW: Memory Leaks beheben
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo nochmal.
Habe jetzt ein Programm welches mir anzeigt, in welcher Zeile des Codes die Leaks auftreten..
Es sind so einige Leaks :D direkt nach dem Start sogar 221 :(
Davon kommen die meisten aber nur 1x vor, im Anhang befindet sich ein Ausschnitt von denen, die am Häufigstens vorkommen.

Allerdings sehen die meisten Zeilen die mir das Programm liefert dann so aus:
Delphi-Quellcode:
AdImageList.LoadFromFile( 'bilder/bilder.ail' );

temp := TAdImage.Create(FParent);

Add(temp);

LoadFromStream(ms);

Rects.Add(AdRect(0,0,FWidth,FHeight));

new(ar);
ar^ := ARect;
inherited Add(ar);

LoadFromXML(xml.Root);
Die meisten Fehler spuckt also Andorra 2D aus.
Allerdings weiss ich jetz überhaupt nicht wie ich die beheben soll, bzw. wie Andorra anders nutzen soll!?

Andorra müsste aber doch eig. funktionieren, da es viele Spiele gibt die damit programmiert wurden etc.
Bei mir steigt der Speicher zum Teil pro sekunde um 4-5 mb!!!

Hilfe :pale:

himitsu 19. Dez 2010 02:32

AW: Memory Leaks beheben
 
Gibst du die Form, bzw. Andorra auch wieder frei?
Jedenfalls steht da in dem Bild irgendwas von Form1 mit drin.


Zitat:

Zitat von w4rheart (Beitrag 1069303)
Gibt es für Delphi nicht evtl. so eine Art Addon eines Garbage Collectors wie bei C?

pühhh, wir programmieren ordentlich und schlampen nicht so rum ... wir brauchen sowas nicht :tongue:

Zitat:

Zitat von w4rheart (Beitrag 1069307)
hab delphi 7

Sowas kann man übrigens in seinem Forenprofil angeben, oder man ibt sowas eben immer mit im Eingangspost an damit nicht ständig nachgefragt werden muß.

Zitat:

Zitat von w4rheart (Beitrag 1069307)
wenn ich System enbinden will kommt Bezeichner redefiniert.

Die Units System (wie schon genannt), SysInit und implizit auch die SysConst werden immer automatisch mit eingebunden.

hoika 19. Dez 2010 08:33

AW: Memory Leaks beheben
 
Hallo,

Delphi-Quellcode:
AdImageList.LoadFromFile( 'bilder/bilder.ail' );
Hast du auch irgendwo ein AdImageList.Clear bzw. AdImageList.Free ?

Du lädst einen Haufen Sachen, erzeugst Speicher (new ()ar),
aber ich sehe nirgendwo eine Freigabe nach der Benutzung.

Unter D7 könntest du auch memcheck benutzen.
Das hat den Vorteil, dass beim Beenden per Exeption die Stellen angeprungen werden,
wo er Speicher angefordert wurde.


Heiko

igel457 19. Dez 2010 10:37

AW: Memory Leaks beheben
 
Hi,

mir ist nur ein Memoryleak in Andorra 2D bekannt, und das tritt unter Umständen beim Reinitialisieren von Andorra 2D auf (also TAdDraw.Finalize und Initialze in einer Kette).

Die von deinem Leak-Checker angezeigten Zeilen deuten aber eher darauf hin, dass du einfach manche Objekte nicht richtig frei gibst - um genau zu sein deine Imagelist, da diese natürlich eine Reihe von TAdImages lädt und die TAdImages wiederum in den aufgelisteten Operationen Speicher reservieren. Die TAdImagelist würde dann auch die Images wieder frei geben und diese den von sich reservierten Speicher.

Hoffe das hilft,
Andreas

alzaimar 19. Dez 2010 10:42

AW: Memory Leaks beheben
 
Neben den schon erwähnten FastMM4 und MemCheck o.ä. solltest Du dir angewöhnen, das, was Du allokierst auch im gleichen Kontext freizugeben.

Beispiel:
Delphi-Quellcode:
Var
  localObject : TSomeOBject;

Begin
  localObject := TSomeObject.Create;
  Try
    DoSomethingWith(localObject);
  Finally
    localObject.Free
  End
End;
...
Type
  TSomeObject = Class (TSomeOtherObject)
  private
  fObject : TFoobar;
...

Constructor TSomeObject.Create;
begin
  inherited;
  fObject := TFoobar;
end;

Destructor TSomeObject.Destroy;
Begin
  fObject.Free;
  inherited
End;

w4rheart 19. Dez 2010 11:55

AW: Memory Leaks beheben
 
Danke für all Eure Tips, die haben mir schonmal weiter geholfen.

@igel457 Du hast Recht, die Imagelist wurde nicht freigegeben. VOn Andorra2d aus treten jetzt keine Memory Leaks mehr auf.

Ich konnte den Leak auf folgende Prozedur zurückführen:

Delphi-Quellcode:
function Textwerkzeug.wortAn( pText: string; wortNummer: integer ): string;
var
  lText: string;
begin
  if copy( pText, length( pText ) - 1, 2 ) = CRLF then
    pText := copy( pText, 1, length( pText ) - 2 ); //LEAK
  lText := pText;
  while ( ansiPos( zTrennung, lText ) > 0 ) and ( wortNummer > 1 ) do begin
    delete( lText, 1, ansiPos( zTrennung, lText ) + length( zTrennung ) - 1 );
    dec( wortNummer );
  end;
  if wortNummer = 1 then
    if ansiPos( zTrennung, lText ) > 0 then
      result := copy( lText, 1, ansiPos( zTrennung, lText ) - 1 ) //LEAK
    else
      result := lText
  else
    result := '';
end;
Allerdings verstehe ich nicht genau wieso hier ein Memory Leak auftritt.
Das (pText/result über den copy Befehl) sind doch strings und keine Objekte? Wie soll man die denn freigeben/löschen?

Sir Rufo 19. Dez 2010 12:17

AW: Memory Leaks beheben
 
Delphi-Quellcode:
pText
riecht ein wenig danach, als ob du den irgendwo als PChar o.ä. definiert hast und damit dann die Procedure aufrufst.

Musst du das veränderte pText zwingend wieder zurückgeben?
Wenn nicht, dann kannst du das auch so machen:
Delphi-Quellcode:
function Textwerkzeug.wortAn( const pText: string; wortNummer: integer ): string;
var
  lText: string;
begin
  if copy( pText, length( pText ) - 1, 2 ) = CRLF then
    lText := copy( pText, 1, length( pText ) - 2 )
  else
    lText := pText;
  while ( ansiPos( zTrennung, lText ) > 0 ) and ( wortNummer > 1 ) do begin
    delete( lText, 1, ansiPos( zTrennung, lText ) + length( zTrennung ) - 1 );
    dec( wortNummer );
  end;
  if wortNummer = 1 then
    if ansiPos( zTrennung, lText ) > 0 then
      result := copy( lText, 1, ansiPos( zTrennung, lText ) - 1 ) //LEAK
    else
      result := lText
  else
    result := '';
end;
Eigentlich sollte man es vermeiden, die Parameter zu verändern es sei denn, die sollen auch bewusst wieder zurückgeliefert werden. (wortNummer)
Dann sollte man vor die Parameter aber auch ein
Delphi-Quellcode:
var
setzen.
Beim Benutzen der Func/Proc ist es einem dann auch bewusst, dass der Übergabeparameter nachher verändert sein kann.

himitsu 19. Dez 2010 12:28

AW: Memory Leaks beheben
 
Könnte auch Parameter heißen.
(nja, dieses Typen-Prefix, welches du meins, ist eh eine Unsitte)

Was soll das Delphi-Referenz durchsuchenAnsiPos, bei einem String (nicht AnsiString)?

Sir Rufo 19. Dez 2010 13:14

AW: Memory Leaks beheben
 
Darum ja auch nur "es riecht danach" ;)

w4rheart 19. Dez 2010 13:17

AW: Memory Leaks beheben
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also die Unit die ich da benutze, habe ich nicht selbst geschrieben.
Es ist Textwerkzeugunit die ich im Internet gefunden habe.
(Ist im Anhang)

Aufgerufen wird das ganze in dieser Prozedur:
Delphi-Quellcode:
procedure Verbindung.ClientSocketRead( Sender: TObject; Socket: TCustomWinSocket );
var
  lNachricht, lEineNachricht: Zeichenkette;
begin
  lNachricht := Socket.receiveText;
  hatTextwerkzeug.setzeTrennung( NTrenner );
  repeat
    lEineNachricht := hatTextwerkzeug.wortAn( lNachricht, 1 ); //LEAK
    if
      hatTextwerkzeug.laenge( lEineNachricht ) = hatTextwerkzeug.laenge( lNachricht ) then
      lNachricht := ''
    else

      lNachricht := hatTextwerkzeug.textOhne( lNachricht, 1, hatTextwerkzeug.laenge( lEineNachricht ) + hatTextwerkzeug.laenge( NTrenner ) );
    if lEineNachricht <> '' then
      hatListe.haengeAn( ZeichenketteObjekt.init( lEineNachricht ) );
    if zMitProtokoll then
      hatClientKontrollfenster.memo1.lines.add( 'Verbindung liest ' + lEineNachricht );
  until lNachricht = '';
end;

Sir Rufo 19. Dez 2010 13:27

AW: Memory Leaks beheben
 
Wo wird
Delphi-Quellcode:
hatTextwerkzeug
initialisiert und wieder freigegeben?
Wie ist
Delphi-Quellcode:
Zeichenkette
definiert?

w4rheart 19. Dez 2010 13:35

AW: Memory Leaks beheben
 
Liste der Anhänge anzeigen (Anzahl: 1)
hatTextwerkzeug wird in
Delphi-Quellcode:
constructor Verbindung.init( pIPAdresse: Zeichenkette; pPortNr: GanzeZahl;
  pMitProtokollieren: Wahrheitswert );
begin
  hatTextwerkzeug := Textwerkzeug.init;
..
end;
initialisiert.

Delphi-Quellcode:
  ZeichenketteObjekt = class
  private
    zInhalt: Zeichenkette;
  public
    constructor init( pInhalt: Zeichenkette );
    procedure setzeInhalt( pInhalt: Zeichenkette );
    function Inhalt: Zeichenkette;
    destructor gibFrei;
  end;

constructor ZeichenketteObjekt.init( pInhalt: Zeichenkette );
begin

  zInhalt := pInhalt;
end;

procedure ZeichenketteObjekt.setzeInhalt( pInhalt: Zeichenkette );
begin
  zInhalt := pInhalt;
end;

function ZeichenketteObjekt.Inhalt: Zeichenkette;
begin
  result := zInhalt;
end;

destructor ZeichenketteObjekt.gibFrei;
begin
end;
Zeichenkette ist ein string

DeddyH 19. Dez 2010 13:43

AW: Memory Leaks beheben
 
Das ist ja gruselig. Zum Einen heißt der vorgegebene Destruktor nicht GibFrei, sondern Destroy und sollte überschrieben werden. Zum Anderen: wenn schon eine Klasse, dann auch bitte mit Properties und entsprechenden Getter- und Setter-Methoden. Mir scheint, da hat sich jemand diese komische mSum-Unit genau angeschaut und abgekupfert.

w4rheart 19. Dez 2010 14:42

AW: Memory Leaks beheben
 
Ja, ich weiss es auch nicht.
Ich komme auch nicht mehr weiter, bzw. weiss nicht was ich tun soll...
Wenn das Programm läuft, steigt einfahc die ganze Zeit die Ram Auslastung...
und irgendwann stürzt es dann halt ab...

DeddyH 19. Dez 2010 14:59

AW: Memory Leaks beheben
 
Wozu zum Henker wird denn dieses komische Zeichenkettenobjekt benötigt, wenn es doch nichts Besonderes tut?

w4rheart 19. Dez 2010 15:12

AW: Memory Leaks beheben
 
hier:
Delphi-Quellcode:
procedure Verbindung.ClientSocketRead( Sender: TObject; Socket: TCustomWinSocket );
var
  lNachricht, lEineNachricht: Zeichenkette;
begin
  lNachricht := Socket.receiveText;
  hatTextwerkzeug.setzeTrennung( NTrenner );
  repeat
    lEineNachricht := hatTextwerkzeug.wortAn( lNachricht, 1 );
    if
      hatTextwerkzeug.laenge( lEineNachricht ) = hatTextwerkzeug.laenge( lNachricht ) then
      lNachricht := ''
    else

      lNachricht := hatTextwerkzeug.textOhne( lNachricht, 1, hatTextwerkzeug.laenge( lEineNachricht ) + hatTextwerkzeug.laenge( NTrenner ) );
    if lEineNachricht <> '' then
      hatListe.haengeAn( ZeichenketteObjekt.init( lEineNachricht ) ); //HIER
    if zMitProtokoll then
      hatClientKontrollfenster.memo1.lines.add( 'Verbindung liest ' + lEineNachricht );
  until lNachricht = '';
end;
Allerdings kann ich nicht auf gibfrei, free oder sonst was zugreifen.

Sir Rufo 19. Dez 2010 15:17

AW: Memory Leaks beheben
 
Hier handelt es sich wieder um diese verhunzte (mir liegt ja eher vergewaltigte) Unit-Sammlung aus dem Schulunterricht.

Helfen kann man da nur wenig, denn diese Sammlung ist
- nicht wirklich Standard
- teilweise sogar falsch aufgebaut
- verdeutscht mit bisserl englisch
- wahrscheinlich auch noch ansteckend :mrgreen:
- und hier im Forum auch nicht bekannt (aus oben genannten Gründen)

nochmal zu hatTextwerkzeug:

Wo wird das wieder freigegeben?

DeddyH 19. Dez 2010 15:18

AW: Memory Leaks beheben
 
ReceiveText gibt einen String zurück. Ich wundere mich eigentlich, dass der Code überhaupt kompiliert wird. Nochmal: wozu diese komische Klasse, wenn man genausogut den Datentyp String verwenden kann?

Sir Rufo 19. Dez 2010 15:20

AW: Memory Leaks beheben
 
Zitat:

Zitat von DeddyH (Beitrag 1069412)
ReceiveText gibt einen String zurück. Ich wundere mich eigentlich, dass der Code überhaupt kompiliert wird. Nochmal: wozu diese komische Klasse, wenn man genausogut den Datentyp String verwenden kann?

Da hab ich mich auch erst verhauen.

lNachricht ist vom Typ Zeichenkette und das ist String
ZeichenketteObject ist ein Object ;)

DeddyH 19. Dez 2010 15:22

AW: Memory Leaks beheben
 
:wall: Wo liegt eigentlich der Sinn darin, Bezeichner für bereits existierende Datentypen unbedingt eindeutschen zu wollen? Da muss man ja durcheinanderkommen.

Sir Rufo 19. Dez 2010 15:27

AW: Memory Leaks beheben
 
Zitat:

Zitat von DeddyH (Beitrag 1069414)
:wall: Wo liegt eigentlich der Sinn darin, Bezeichner für bereits existierende Datentypen unbedingt eindeutschen zu wollen? Da muss man ja durcheinanderkommen.

Hatte ich ja schon so eine Vermutung http://www.delphipraxis.net/1068099-post15.html

DeddyH 19. Dez 2010 15:31

AW: Memory Leaks beheben
 
[OT] Man müsste denjenigen, der diese Units verbrochen hat, dazu zwingen, "Jehova" zu sagen :mrgreen: [/OT]

Sir Rufo 19. Dez 2010 15:40

AW: Memory Leaks beheben
 
Wenigstens sollte ein CompilerSchalter drin sein:
Delphi-Quellcode:
{$IFDEF Lehrer}
...
{$ELSE}
ShowMessage( 'Merkst du es noch?' );
{$ENDIF}

w4rheart 19. Dez 2010 15:46

AW: Memory Leaks beheben
 
Nun gut :D
wir halten also fest: Die Units sind vermurkst.
Trotzdem muss man doch den MemoryLeak da raus bekommen können oder?

Zeichnkette Objekt wird hier freigegeben:
Delphi-Quellcode:
procedure Tclientverbindung.ClientSocketRead( Sender: TObject; Socket:
  TCustomWinSocket );
var
  lNachricht: Zeichenkette;
begin
  inherited ClientSocketRead( Sender, Socket );
  while not hatListe.istLeer do begin
    hatListe.zumAnfang;
    lNachricht := ZeichenketteObjekt( hatListe.aktuelles ).inhalt;
    hatListe.entferneAktuelles; //Hier denke ich zumindest
    bearbeiteNachricht( lNachricht );
  end;
end;
entferneAktuelles macht folgendes:
Delphi-Quellcode:
procedure Liste.entferneAktuelles;
var
  lZeiger: Knoten;
begin
  if not ( istDavor or istDahinter ) then begin
    if hatAktuelles = hatAnfang then
      hatAnfang := hatAnfang.nachfolger
    else begin
      hatAktuelles.vorgaenger.setzeNachfolger( hatAktuelles.nachfolger );
      hatAktuelles.nachfolger.setzeVorgaenger( hatAktuelles.vorgaenger );
    end;
    lZeiger := hatAktuelles;
    hatAktuelles := hatAktuelles.nachfolger;
    lZeiger.free; //Hier wird es freigebgen
    dec( zLaenge );
  end
end;
Tut mir Leid, wenn ich euch mit diesem ganzen Kram "belästige" ;)
Wie schon richtig vermutet, habe ich diese Units aus der Schule...
Das dieses ganze Eingedeutsche nicht so schön ist, dem würde ich ebenfalls zustimmen.

Was gibt es denn für Alternativen?
Die Units werden dafür gebraucht eine Netzwerkverbindung aufzubauen und zwischen einem Server und Clients Daten auszutauschen.
Gibt es evtl. andere Projekte/BibliothekenProgramme die "schöner" sind?

MfG

DeddyH 19. Dez 2010 15:50

AW: Memory Leaks beheben
 
Da scheint auch noch eine doppelt verkettete Liste im Spiel zu sein :pale:. Schmeiß doch die ganzen Schulunits mal komplett aus dem Projekt (und aus dem Gedächtnis) und fang von vorn an. Du könntest Dir z.B. mal die Demos von Delphi ansehen, da war IIRC auch eins mit Sockets dabei, ansonsten zieh Dir mal die Tutorials vom Delphi-Treff rein.

Sir Rufo 19. Dez 2010 16:02

AW: Memory Leaks beheben
 
Deine Vermutung ist falsch, da wird kein relevantes Objekt freigegeben.

Es geht hier leider nicht um "schön" sondern um falsch.
Somit kann nicht ausgeschlossen werden, dass die MemLeaks von den vergewaltigten Destruktoren kommt.

Ein Destruktor wird so implementiert und nicht anders
Delphi-Quellcode:
destructor Destroy; override;

...

destructor TFoo.Destroy;
  begin
   
    inherited;
  end;
Macht man das anders dann kann es rumsen (MemLeaks).

Desweiteren muss man immer aufpassen wo/wer ein Objekt erzeugt. Da/der sollte sich auch um die Freigabe kümmern.

Und natürlich kann man die MemLeaks da auch rausbekommen

- komplett neuschreiben ohne diese Units
- alle Units durcharbeiten, korrigieren und dann den Source überprüfen

Ich würde mich aber wundern, wenn du hier jemand findest, der das für Dich übernimmt, denn das ist in 5-10 Minuten nicht erledigt und du wirst wahrscheinlich auch keine Lust haben dafür zu bezahlen, genauso wie hier wohl keiner Lust hat ein paar Tage daran herumzuschrauben.

Sorry to tell bad news

w4rheart 19. Dez 2010 16:13

AW: Memory Leaks beheben
 
Na gut, dann aber schon mal vielen Dank für Eure Hilfe!!!

Ich werd mich mal mit den Tutorials von Delphi-Treff befassen.

Noch ein schönes Restwochenende ;)

w4rheart 21. Dez 2010 16:47

AW: Memory Leaks beheben
 
Hallo nochmal!

Ich lese geradefolgendes Tutorial über Multithreading:
http://wiki.delphigl.com/index.php/T...Multithreading

Kann man mit Threads MemLeaks beheben, in dem man die kritischen Stellen einfach in einen Thread packt, welcher später freigegeben wird?
Diese Stelle hat mich auf den Gedanken gebracht:
Zitat:

Thread.FreeOnTerminate := True;
// FreeOnTerminate bedeutet sobald der Thread die Procedure Execute
// verlassen hat wird sein Speicher wieder von alleine Frei gegeben.
// andernfalls müsste später im Programm Thread.Free aufgerufen werden.
Wahrscheinlich funktioniert das nicht, das wäre ja auch zu schön... ?

himitsu 21. Dez 2010 16:50

AW: Memory Leaks beheben
 
Zitat:

Zitat von w4rheart (Beitrag 1069833)
Kann man mit Threads MemLeaks beheben

Nein.

FreeOnTerminate bezieht sich nur auf das Thread-Objekt.

DeddyH 21. Dez 2010 18:26

AW: Memory Leaks beheben
 
MemoryLeaks kann man nur durch gewissenhafte Programmierung verhindern.

fui-tak 21. Dez 2010 18:54

AW: Memory Leaks beheben
 
Ich weis ja nicht, in wie weit du das bisherige schon verworfen hast, aber hier ich hab noch einen Fehler gefunden:

Edit: doch nicht...

w4rheart 22. Dez 2010 10:41

AW: Memory Leaks beheben
 
hello again!

Mir ist aufgefalle, dass der Memory Leak erst dann so extrem wird, wenn ein Spieler (Raumschiff) stirbt.
-> d.h. es liegt sehr wahrscheinlich doch nicht an den Netzwerkklassen, sondern daran, wie dieses Raumschiff gelöscht wird.

Ich poste mal eben wie es created und destructed wird, evtl. ist dort ein Fehler den ich nicht sehe:
Delphi-Quellcode:
  TRaumschiffSprite = class( TMySprite )
  public
    nick: string;
    farbe: TColor;
    leben, lebenMax: Extended;
    gesundheitsbalken: TBalken;
    spielerid: integer;
    constructor Create( AParent: TSprite ); override;
  end;

procedure TSpriteVerwaltung.neuesRaumschiff( pID: Integer; pSpielerID: integer; pFarbe: TColor; pX, pY, pLaenge, pKurs: Integer; pVX, pVY, pAX, pAY, pLeben, pLebenMax: Extended );
// Erstellt ein neues Raumschiff, weist ihm die entsprechenden Eigentschaften zu
// und fügt es in die Liste ein
var
  raumschiff: TRaumschiffSprite;
  particle: TAdBillboardParticle;
begin
  raumschiff := TRaumschiffSprite( getSprite( pID ) );
// es wird nur dann created, wenn das Raumschiff nicht bereits exisitiert.
//wenn es existiert werden nur unten die Werte wie x,y positiongeupdated etc.
  if raumschiff = nil then begin
    raumschiff := TRaumschiffsprite.Create( form1.AdSpriteEngine ); //hier wird das Raumschiff created
    raumschiff.id := pID;
    raumschiff.gesundheitsbalken := TBalken.Create( form1.AdSpriteEngine, 26, 3 );
    Add( raumschiff );
  end;

  with raumschiff do begin
    spielerid := pSpielerID;
    farbe := pFarbe;
    Angle := pKurs;
    x := pX - Width / 2;
    y := py - Height / 2;
    vx := pVX;
    vy := PVY;
    ax := pAX;
    ay := pAY;
    color := farbe;
    leben := pLeben;
    lebenMax := pLebenMax;
    gesundheitsbalken.x := x + 7;
    gesundheitsbalken.y := y + 40;
    gesundheitsbalken.Aktualisieren( lebenMax, leben, pVX, pVY, pAX, pAY ); // Lebensbalken aktualisieren (Breiten, v, a)
  end;
end;
Nun zum interessanten Teil, dem Löschen:
Delphi-Quellcode:
function TBefehlLoeschen.Ausfuehren( pParameter: string ): boolean;
var
  lID: integer;
  lSprite: TImageSpriteEx;
begin
try
  //Sprite in der Liste suchen und das Listenobjekt löschen
  lID := StrToInt( pParameter );
  lSprite := Form1.SpriteVerwaltung.getSprite( lID );
  Form1.SpriteVerwaltung.Remove( lSprite );
  if lSprite is TRaumschiffSprite then
  begin
    TRaumschiffSprite( lSprite ).gesundheitsbalken.Free;
  end;
//löschen des eigentlichen Sprites über Andorra
  lSprite.dead;
  result := true;
except
  on E : Exception do
    ShowMessage(E.ClassName+' error raised, with message : '+E.Message);
  result:=false;
end;
end;
Also wie gesagt, nach dem das erste mal ein Raumschiff zerstört wird, tritt dieser extreme Memory Leak auf.
Ist irgendwas mit meiner Löschen Methode falsch?

Wäre sehr nett, wenn Ihr mir nochmal weiterhelfen könntet :)
MfG


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:08 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