AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi IdTCPServer + MemoryLeak
Thema durchsuchen
Ansicht
Themen-Optionen

IdTCPServer + MemoryLeak

Ein Thema von azury · begonnen am 17. Feb 2010 · letzter Beitrag vom 8. Apr 2010
Antwort Antwort
azury

Registriert seit: 18. Dez 2008
8 Beiträge
 
#1

IdTCPServer + MemoryLeak

  Alt 17. Feb 2010, 17:47
Hallöchen,

Ich hab wieder mal ein Problemchen, unzwar schau ich mir gerade die Indy Components für TCP verbindungen an
und musste feststellen, dass es scheinbar ein paar Probleme damit gibt.
(Indy 10 von Turbo Delphi)
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, IdTCPServer, IdComponent, IdContext;

type
  TMain = class(TForm)
    RichEdit1: TRichEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure OnConnect(AContext: TIdContext);
  public
    { Public-Deklarationen }
    Server: TIdTCPServer;
    procedure Log(Text: String; Farbe: Byte = 0);
  end;

var
  Main: TMain;

implementation

{$R *.dfm}

{ TForm1 }

procedure TMain.FormCreate(Sender: TObject);
begin
  ReportMemoryLeaksOnShutdown := True;

  Server := TIdTCPServer.Create(self);
  Server.DefaultPort := 1307;
  Server.OnConnect := OnConnect;
end;

procedure TMain.FormDestroy(Sender: TObject);
begin
  if (Server.Active) then
    Server.Active := False;
  Server.Free;
end;

procedure TMain.Log(Text: String; Farbe: Byte = 0);
var
  aFont: TFont;
begin
  aFont := TFont.Create;
  aFont.Name := 'Courier';
  aFont.Size := 10;
  case Farbe of
    0: aFont.color := clSilver;
    1: aFont.Color := clWhite;
    2: aFont.Color := clRed;
    3: aFont.color := clYellow;
    4: aFont.color := clLime;
    5: aFont.color := clAqua;
  end;
  RichEdit1.SelAttributes.Assign(aFont);
  RichEdit1.Lines.add(Format('[%s]: %s',[TimeToStr(now),Text]));
  aFont.Free;
end;

procedure TMain.OnConnect(AContext: TIdContext);
begin
  with aContext.Binding do
  begin
    Log('Incoming connection from '+PeerIP);
    Log('Checking IP...');
    Log('Connection Accepted from '+PeerIP);
  end;
end;

end.
Das ist der Code und ich bekomme folgende Message:
Zitat:
---------------------------
Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:

1 - 12 bytes: TIdThreadSafeInteger x 1
21 - 28 bytes: TIdCriticalSection x 2
---------------------------
OK
---------------------------
Tja das sagt ja eigentlich nicht viel aus, aber vielleicht kann mir einer mal Verraten, wo ich sowas finde. Also die Entstehung der Leaks.

//Edit
Achja, es verbindet übrigends niemand, ich schließe das Programm ja gleich wieder.
Und ja, ich weiß, dass ich keine Prüfung der IP programmiert hab

CROSSPOST:
Delphi-forum.de
  Mit Zitat antworten Zitat
ele

Registriert seit: 18. Feb 2009
129 Beiträge
 
Delphi 2010 Professional
 
#2

Re: IdTCPServer + MemoryLeak

  Alt 17. Feb 2010, 18:05
Das ist bekannt, von den Indy-Entwicklern so gewollt und in neueren Delphi-Versionen behoben worden, indem die Leaks registriert werden.

Kein Grund zur Sorge, die Leaks sind zwar unschön, da beim Programmende (im Debugger) ein Dialog angezeigt wird. Der Speicher wird ja sowieso vom Betriebssystem freigegeben sobald das Programm beendet wird.
  Mit Zitat antworten Zitat
azury

Registriert seit: 18. Dez 2008
8 Beiträge
 
#3

Re: IdTCPServer + MemoryLeak

  Alt 17. Feb 2010, 18:12
Hab mir schon die neueste Indy gezogen (10.0.53 oder so) und die Pas reingeschmissen, damit der das (hoffentlich) neu compiliert.
Trotzdem ändert das nichts an dem Leak.
Ich würde den trotzdem gerne weghaben wollen, da ich sonst immer wieder drauf Stoße und wenn ich noch selbst wo leaks einbaue, muss ich erstmal schauen wo die sind.
  Mit Zitat antworten Zitat
ele

Registriert seit: 18. Feb 2009
129 Beiträge
 
Delphi 2010 Professional
 
#4

Re: IdTCPServer + MemoryLeak

  Alt 17. Feb 2010, 18:18
Es sind immer die selben Leaks von Indy, da fallen deine eigenen schon auf.

Das Problem liegt daran, dass du wahrscheinlich FastMM benutzt. Dieses besitzt zwar eine Funktion um bekannte leaks zu registrieren, aber da die Objekte welche die Leaks verursachen in Indy im Implementation-Abschnitt deklariert sind, hast du darauf keinen Zugriff. Indy registriert die Leaks zwar für den neuen MemoryManager von Delphi, aber soweit ich weiss nicht für FastMM. Du könntest natürlich den Indy-Source etwas frisieren, dann musst du aber bei zukünftigen Updates die Änderungen nachführen.
  Mit Zitat antworten Zitat
azury

Registriert seit: 18. Dez 2008
8 Beiträge
 
#5

Re: IdTCPServer + MemoryLeak

  Alt 17. Feb 2010, 19:51
//Edit

Okay den Integer hab ich geschafft wegzubekommen aber es ist nur einmal TIdCriticalSection drin
mal gucken ob ich den auch noch raus bekomme....
Okay nun sind beide raus.

Einmal im IdThread
Delphi-Quellcode:
  // This call hangs if not all threads have been properly destroyed.
  // But without this, bad threads can often have worse results. Catch 22.
  TIdThread.WaitAllThreadsTerminated;
  FreeAndNil(GThreadCount);
Das war ausgeklammert, wie dort beschrieben.

Und einmal im IdComponent:
Delphi-Quellcode:
destructor TIdComponent.Destroy;
begin
  inherited;
  // After inherited - do at last possible moment
  GStackCriticalSection.Acquire; try
    Dec(GInstanceCount);
    if GInstanceCount = 0 then begin
      // This CS will guarantee that during the FreeAndNil nobody will try to use
      // or construct GStack
      FreeAndNil(GStack);
    end;
  finally
    GStackCriticalSection.Release;
    FreeAndNil(GStackCriticalSection);
  end;
Da hab ich einfach das FreeAndNil(GStackCriticalSection); angefügt.
Keine Ahnung ob das okay ist was ich da mache, aber es entstehen keine Memleaks mehr.
Wenn einer gute gründe hat warum man das nicht machen sollte, immer her damit.
  Mit Zitat antworten Zitat
Assertor

Registriert seit: 4. Feb 2006
Ort: Hamburg
1.296 Beiträge
 
Turbo C++
 
#6

Re: IdTCPServer + MemoryLeak

  Alt 8. Apr 2010, 22:13
Hallo,

mal etwas im Nachtrag zum Thread:

Zitat von ele:
Indy registriert die Leaks zwar für den neuen MemoryManager von Delphi, aber soweit ich weiss nicht für FastMM. Du könntest natürlich den Indy-Source etwas frisieren, dann musst du aber bei zukünftigen Updates die Änderungen nachführen.
Das stimmt nicht, Indy registiert die Leaks über System.RegisterExpectedMemoryLeak(). Das leitet an den jeweiligen MM um (also SysRegisterExpectedMemoryLeak bzw. FastMM4). Alles auf Korrektheit geprüft in Rücksprache mit dem Autor von FastMM seinerzeit.

Zitat von azury:
Okay den Integer hab ich geschafft wegzubekommen aber es ist nur einmal TIdCriticalSection drin
mal gucken ob ich den auch noch raus bekomme....
Okay nun sind beide raus.

Einmal im IdThread
Delphi-Quellcode:
  // This call hangs if not all threads have been properly destroyed.
  // But without this, bad threads can often have worse results. Catch 22.
  TIdThread.WaitAllThreadsTerminated;
  FreeAndNil(GThreadCount);
Das war ausgeklammert, wie dort beschrieben.
Das kann man machen (wobei es einfacher ist FREE_ON_FINAL für das Projekt zu definieren, als im Source zu ändern) - aber nur wenn 100% sichergestellt ist, dass jeder Thread sauber beendet wird. Da leider die meisten Entwickler gerade hier Probleme haben (unwissentlich), bleibt es per default so wie bisher.

Zitat von azury:
Und einmal im IdComponent:
Delphi-Quellcode:
destructor TIdComponent.Destroy;
begin
  inherited;
  // After inherited - do at last possible moment
  GStackCriticalSection.Acquire; try
    Dec(GInstanceCount);
    if GInstanceCount = 0 then begin
      // This CS will guarantee that during the FreeAndNil nobody will try to use
      // or construct GStack
      FreeAndNil(GStack);
    end;
  finally
    GStackCriticalSection.Release;
    FreeAndNil(GStackCriticalSection);
  end;
Da hab ich einfach das FreeAndNil(GStackCriticalSection); angefügt.
Keine Ahnung ob das okay ist was ich da mache, aber es entstehen keine Memleaks mehr.
Wenn einer gute gründe hat warum man das nicht machen sollte, immer her damit.
Grund: Access Violations. Du gibst bei 1. Durchlauf des Destruktors die CriticalSection bereits frei. Und was ist, wenn eine 2. Instanz nun in den Destruktor durchläuft?

Die Leaks haben ihre Berechtigung. Für berechtigte Ausnahmen gibt es FREE_ON_FINAL.

Gruß,
Assertor
Frederik
  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 04:27 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