AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

FastMM und aktuelles Delphi

Ein Thema von Der schöne Günther · begonnen am 5. Jul 2016 · letzter Beitrag vom 12. Apr 2017
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.195 Beiträge
 
Delphi 10.4 Sydney
 
#11

AW: FastMM und aktuelles Delphi

  Alt 12. Apr 2017, 09:50
Hallo zusammen,

ich habe zZ ein ähnliches Problem mit der Verwendung von FastMM in Verbindung mit Frames, welche ein Interface implementieren:
Ich vermute du musst die Refernzzählung deaktivieren.
Ansonsten hast du u.U. doppelte Freigabe. Einerseits über den Parent/owner und andererseits über das Interface.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
Headbucket

Registriert seit: 12. Dez 2013
Ort: Dresden
172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#12

AW: FastMM und aktuelles Delphi

  Alt 12. Apr 2017, 11:49
Das war auch mein erster Gedanke.

Mein Frame ist ja aber von TComponent abgeleitet. Wird dort nicht so oder so die Referenzzählung deaktiviert?
Ansonsten wäre ich über Hinweise dankbar, wie man diese abschaltet

Und was hat FastMM damit zu tun? Wenn das ganze doppelt freigegeben wird, dann sollte doch IMMER ein Fehler kommen und nicht nur mit FastMM.

Danke aber schonmal für die Antwort!

Grüße
  Mit Zitat antworten Zitat
Der schöne Günther
Online

Registriert seit: 6. Mär 2013
6.156 Beiträge
 
Delphi 10 Seattle Enterprise
 
#13

AW: FastMM und aktuelles Delphi

  Alt 12. Apr 2017, 11:58
Der Ablauf ist doch folgender
- Erstelle Frame
- Habe interface-basierte Referenz auf das Frame-Objekt in einem Objekt "X"
- Zerstöre Frame
- Habe weiterhin interface-basierte Referenz auf das Frame-Objekt
- Zerstöre Objekt "X"
- Interface-basierte Referenz wird genullt, versucht Referenzzähler auf den mittlerweile zerstörten Frame zu verringern (also die Methode _Release() aufrufen)


Ohne FastMM kommt hier zur Laufzeit, denke ich, aus einem von zwei Gründen keine Exception
  1. Wenn die Anwendung abgeräumt wird ist der Standard-Speichermanager relativ großzügig was das Herunterschlucken von AVs angeht. Zumindest kommt es mir so vor
  2. Wenn er _Release() auf dem zerstörten Frame aufrufen will bemerkt er nichts ungewöhnliches. Alles klappt wie es soll. Kein Grund sich zu beschweren. Bei FastMM hingegen gibt es eine Einstellung dass beim Zerstören eines Objekts sein gesamter Speicher mit irgendeinem Muster komplett überschrieben wird. Somit ist kein "es könnte noch klappen" mehr möglich, sondern das Aufrufen einer Methode auf einem toten Objekt geht garantiert schief. Das ist bewusst gemacht um solche Fehler zu finden.


Ab Delphi 10.1 Berlin könnte man das Problem ganz gut mit dem [weak]-Attribut angehen, oder? Ich habe mich damit immer noch nicht befasst
  Mit Zitat antworten Zitat
SebastianZ

Registriert seit: 23. Jul 2009
89 Beiträge
 
Delphi 11 Alexandria
 
#14

AW: FastMM und aktuelles Delphi

  Alt 12. Apr 2017, 12:07
Der Ablauf ist doch folgender
- Erstelle Frame
- Habe interface-basierte Referenz auf das Frame-Objekt in einem Objekt "X"
- Zerstöre Frame
- Habe weiterhin interface-basierte Referenz auf das Frame-Objekt
- Zerstöre Objekt "X"
- Interface-basierte Referenz wird genullt, versucht Referenzzähler auf den mittlerweile zerstörten Frame zu verringern (also die Methode _Release() aufrufen)
Aus meiner Sicht liegt hier des Pudels Kern. Ich habe dein Forms.Main wie folgt geändert:

Delphi-Quellcode:
unit Forms.Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  uInterface,
  Frames.MyFrame, Vcl.ExtCtrls;

type
  TMainForm = class(TForm)
    pnl1: TPanel;
  private
    FMyFrame: IMyInterface;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    { Public-Deklarationen }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

constructor TMainForm.Create(AOwner: TComponent);
begin
  inherited;

  FMyFrame := TMyFrame.Create(Self);
  TMyFrame(FMyFrame).Parent := pnl1;
  TMyFrame(FMyFrame).Align := alClient;
end;

destructor TMainForm.Destroy;
begin
  FMyFrame := nil;

  inherited;
end;

end.
Dadurch sollte alles korrekt abgebaut werden.

Bei deiner Variante bleibt die Referenz im Interface stehen, er versucht das dazugehörige Objekt abzubauen, das es nicht mehr gibt, und die Exception kommt.

Geändert von SebastianZ (12. Apr 2017 um 13:12 Uhr) Grund: Create richtig gestellt
  Mit Zitat antworten Zitat
Headbucket

Registriert seit: 12. Dez 2013
Ort: Dresden
172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#15

AW: FastMM und aktuelles Delphi

  Alt 12. Apr 2017, 12:25
Vielen Dank für die Antworten!

Klingt logisch und das manuelle nil-Setzen löst unabhängig von dem im Create zugewiesenen Owner das Problem.

Wird mein Frame dann jetzt nur noch vom Interface freigegeben (in dem Moment, wo ich nil setze), da der Owner keinen Bezug mehr zum Frame hat?

Grüße
Headbucket
  Mit Zitat antworten Zitat
Der schöne Günther
Online

Registriert seit: 6. Mär 2013
6.156 Beiträge
 
Delphi 10 Seattle Enterprise
 
#16

AW: FastMM und aktuelles Delphi

  Alt 12. Apr 2017, 12:34
Nein, ein TFrame leitet sich ab von TComponent. Und wenn du schaust wie in TComponent die MEthoden _AddRef und _Release implementiert sind: Da passiert nichts. Eine TComponent ist immer so vorgesehen dass man sich manuell um ihre Lebenszeit kümmert. Entweder über den Owner. Oder wenn kein Owner da ist, dann über den schlauen Programmierer der weiß wann die Zeit gekommen ist

Siehe auch: http://stackoverflow.com/q/2182612/2298252
  Mit Zitat antworten Zitat
Headbucket

Registriert seit: 12. Dez 2013
Ort: Dresden
172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#17

AW: FastMM und aktuelles Delphi

  Alt 12. Apr 2017, 12:53


Besten Dank!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.034 Beiträge
 
Delphi 12 Athens
 
#18

AW: FastMM und aktuelles Delphi

  Alt 12. Apr 2017, 15:03
Du hast dienen Frame als Interface gespeichert, das sollte man niemals machen.

TComponent hat ein IInterface ohne Referenzzählung.


Die VCL ist leider etras "böswillig", denn die Freigabe wird nicht "nur" über Free und den Owner geregelt, sondern auch der Parent gibt alle Komponenten frei, welche auf ihm liegen, wenn man ihn löscht.

Da die VCL aber die KlassenFelder auf nil setzt, wenn der owner ein Published-Feld mit dem selben Namen besitzt, fällt es meistens nicht auf,
da bei Freigabe eines Objektes auch die Felder genilt werden.
(etwas unglücklich ist, dass die VCL nicht auf den Typ achtet, hart auf TComponent castet und alles überschreibt, was zufällig so heißt)


Deine Interfacevariable ist aber keine [Weak]-Referenz und bleibt somit gesetzt.



PS: FastMM oder nicht FastMM ... seit 2006 ist ein FastMM immer im Delphi drin.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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 12:33 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