Delphi-PRAXiS
Seite 4 von 4   « Erste     234   

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 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 10:10 Uhr.
Seite 4 von 4   « Erste     234   

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