Frage

Ich erbte eine Intraweb App, die eine 2 MB Textdatei von Speicherlecks hatte, wie durch FastMM4 berichtet. Ich habe es bis zu 115 Instanzen einer Klasse undichten 52 Bytes.

Eine kurze Beschreibung des schlechten Schauspielers ist:

TCwcBasicAdapter = class(TCwcCustomAdapter)  
  protected  
    FNavTitleField: TField;  
    function GetAdapterNav(aDataSet: TDataSet): ICwcCDSAdapterNav; override;  
  public  
    constructor Create(aDataSource: TDataSource; aKeyField, aNavTitleField: TField; aMultiple: boolean);  
  end;  

und die Schnittstelle ist:

  ICwcCDSAdapterNav = interface(IInterface)  

Am Bellen ich den falschen Baum, da die Eigenschaft Referenz gezählt? Gibt es Umstände, unter denen die Schnittstelle Eigenschaft die Klasse vor Zerstörung bewahren können?

Hier ist die Implementierung des Verfahrens oben:

function TCwcBasicAdapter.GetAdapterNav(aDataSet: TDataSet): ICwcCDSAdapterNav;
var
  AdapterNav: TCwcCDSAdapterNavBase;
begin
  result := nil;
  if Assigned(aDataSet) then begin
    AdapterNav := TCwcCDSAdapterNavBasic.Create(aDataSet, FKeyField.Index, FNavTitleField.Index);
    try
      AdapterNav.GetInterface(ICwcCDSAdapterNav, result);
    except
      FreeAndNil(AdapterNav);
      raise;
    end;
  end;
end;

mit der Klasse deklariert als:

TCwcCDSAdapterNavBase = class(TInterfacedObject, ICwcCDSAdapterNav)
War es hilfreich?

Lösung

FastMM sollten Sie geben, was durchgesickert und wo es erstellt wurde.
Das würde helfen, es auf die wahr Schuldige Verengung: wer was undicht

Ich bin mir nicht sicher, was wirklich Ihre Frage?
Ihr Code unvollständig ist oder nicht die in Frage. Ihre Klasse keine Schnittstelle Eigenschaft hat noch eine Schnittstelle privaten Feld, nur eine Methode, die eine Schnittstelle zurückgibt, die harmlos ist

Bearbeiten . Ohne den Code Ihres Objekts Umsetzung ICwcCDSAdapterNav zu sehen, können wir nicht sagen, ob es in der Tat Referenz gezählt
Wenn Sie nicht aus TInterfacedObject steigen Sie , stehen die Chancen, , dass es Verweis der nicht gezählt und , dass Sie nicht auf diese verlassen können automagically befreien ...

Sie können einen Blick auf diese geben wollen 2 Coderage Sitzung : Kampf Speicherverluste für Dummies . Es zeigt vor allem, wie FastMM verwenden, um Speicherlecks in Delphi zu verhindern / zu erkennen. War für D2007, aber immer noch relevant für andere Versionen.

Andere Tipps

Sie haben einige gute Antworten bekommen so weit wie FastMM funktioniert. Aber wie für die eigentliche Frage, ja, eine Schnittstelle Objekte können auf zwei verschiedene Arten auslaufen.

  1. Schnittstellen sind nur als Referenz gezählt, wenn die Objekte gehören sie zu Referenzzählung in ihren _AddRef und _Release Methoden implementiert zu haben. Einige Objekte nicht.
  2. Wenn Sie Kreis Schnittstelle Referenzen haben, (Schnittstelle 1 Referenzen Schnittstelle 2, die Schnittstelle verweist 1), dann wird der Referenzzähler wird nie ohne einige spezielle Tricks auf Ihrer Seite auf 0 fallen. Wenn dies Ihr Problem ist, werde ich beziehe mich auf Sie Andreas Hausladen letzten Blog-Beitrag zu diesem Thema.

Wenn Sie 115 Instanzen dieser Klasse undicht sind, dann ist es diese Klasse , die durchgesickert wird. Der Speicher, der von dieser Klasse besetzt, nicht die von den Dingen belegten Speicher darauf bezieht, geleckt wird. Irgendwo, Sie haben 115 Fälle von TCwcBasicAdapter, dass Sie nicht zu befreien.

Darüber hinaus Eigenschaften keine Daten gespeichert werden, egal, sie sind Schnittstellen oder eine andere Art. Nur Felder besetzen Speicher (mit einem verborgenen Raum entlang der Compiler auf die Klasse des Namen zuweist).

Also, ja, sind Sie auf dem Holzweg auf. Ihr Speicherleck ist woanders. Wenn FastMM Ihnen sagt, dass Sie einen Speicherverlust haben, ist es Ihnen nicht auch sagen, wo jeder durchgesickert Instanz zugewiesen wurde. Es hat diese Fähigkeit; Sie müssen möglicherweise einige bedingte Kompilierung Symbole anzupassen, die Funktion zu aktivieren.

Es ist sicherlich keine nur Instanzen dieser Klasse, die undicht sind, though. FastMM sollte auch einige andere Dinge, undichte, wie Instanzen der Klasse oder Klassen berichtet, die die Schnittstelle implementieren.


Auf der Grundlage der Funktion, die Sie hinzugefügt, habe ich angefangen, zu vermuten, dass es wirklich TCwcCDSAdapterNavBase das ist undicht, und dass wegen der atypischen Weg sein könnten Sie für die Erstellung verwenden. Hat der Ausnahmebehandler in GetAdapterNav jemals laufen? Das bezweifle ich; TObject.GetInterface wirft nie explizit eine Ausnahme. Wenn das Objekt die Schnittstelle nicht unterstützt, gibt es False. Alle, die Exception-Handler könnte fangen sind Dinge wie Zugriffsverletzung und illegale Operationen, die Sie sollten wirklich nicht, dass es sowieso zu kontrollieren.

Sie können diese Funktion implementieren mehr direkt wie folgt aus:

if Assigned(FDataSet) then
  Result := TCwcCDSAdapterNavBase.Create(...);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top