AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi FMX: TBitmap.Assign Methode erscheint mir nicht korrekt
Thema durchsuchen
Ansicht
Themen-Optionen

FMX: TBitmap.Assign Methode erscheint mir nicht korrekt

Ein Thema von Sherlock · begonnen am 17. Apr 2018 · letzter Beitrag vom 18. Apr 2018
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.798 Beiträge
 
Delphi 12 Athens
 
#1

FMX: TBitmap.Assign Methode erscheint mir nicht korrekt

  Alt 17. Apr 2018, 12:46
Sorry für den blöden Thread-Titel, aber ich kann mir grad nicht helfen.
Ich habe ein Speicherleck, weil ich durch eine Klassenhierarchie eine Bitmap durchreiche, und auf oberster Ebene die Bitmap der Bitmap eines TImage assigne. Jetzt bekomme ich das Leck nicht gestopft, weil die TBitmap.Assign Methode folgendes treibt:
Delphi-Quellcode:
procedure TBitmap.Assign(Source: TPersistent);
begin
  TMonitor.Enter(Self);
  try
    if Source = nil then
      SetSize(0, 0)
    else if Source is TBitmap then
    begin
      DestroyResources;
      TBitmap(Source).FImage.IncreaseRefCount;
// Warum die nächste Zeile?
      FImage.DecreaseRefCount;
// Ab jetzt ist FImage das Fimage Objekt der Source
      FImage := TBitmap(Source).FImage;
      BitmapChanged;
    end
    else if Source is TBitmapSurface then
      AssignFromSurface(TBitmapSurface(Source))
    else
      inherited;
  finally
    TMonitor.Exit(Self);
  end;
end;
Den in meinen Augen kritischen Abschnitt habe ich kommentiert. Das Problem ist, daß hier ein Assign mit einer Objekt-Zuweisung vermischt wird, und dadurch keine zwei getrennte Objekte entstehen, sondern die sind, eine Ebene tiefer, miteinander verwoben. Falls das so ist, ist das doch Käse. Oder übersehe ich etwas?

Gegenwärtig erzeuge ich massenweise Bitmaps zur Laufzeit, die ich per Assign auf die Oberfläche werfe, und phänotypisch ist alles OK, nur ich verbrate immer mehr Speicher, ohne ihn wirklich freigeben zu können....

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: FMX: TBitmap.Assign Methode erscheint mir nicht korrekt

  Alt 17. Apr 2018, 12:52
BitMaps sind intern referenzgezählt.

Die alte Referenz reduzieren, weil gleich diese Referenz gelöscht/überschrieben wird, mit dem Verweis auf den neuen Inhalt.
Darum auch darüber das IncreaseRefCount im anderen Bitmap, da hier gleiche eine Referenz auf dessen Inhalt gespeichert wird.
Hier eben alles manuell und keine autoamtische Referenzzählung. (Interface oder ARC)

So lange beide Bitmaps nichts an ihrem Inhalt ändern, verweisen sie auf den selben Inhalt und sparen so Speicher.
Bei Änderungen sollte dann wohl irgendwo der Inhalt kopiert und mit einer "echten" Kopie weitergearbeitet werden.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (17. Apr 2018 um 12:58 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.798 Beiträge
 
Delphi 12 Athens
 
#3

AW: FMX: TBitmap.Assign Methode erscheint mir nicht korrekt

  Alt 17. Apr 2018, 14:02
Das ist nicht wirklich befriedigend. Mein Problem ist zB folgendes (ich habe mehrere Bitmap Lecks, aber das hier ist sehr einfach erklärt):
Ich zeichne ein recht umfangreiches Koordinatengitter mit wiederholenden Spines. Das dauert je nach Rechner seine Zeit, weshalb ich es einfach nach Erzeugung abspeichere und dann immer wieder bei Bedarf per TBitmap.CreateFromFile lade. Dieses Objekt Assigne ich einem TImage, daß auf meiner Form liegt. Das Koordinatengitter wird auflösungsabhängig erzeugt/gespeichert/geladen. Wenn die Fenstergröße geändert wird, werden anders skalierte Gitter benötigt, und die alten weggeworfen. Weil ich bisher nicht wirklich wegwarf, sondern "drüber assignte" hab ich also ein Speicherleck. Jetzt wollte ich die alte Bitmap des TImages wegwerfen, aber das geht ja gar nicht.

Was tun?

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: FMX: TBitmap.Assign Methode erscheint mir nicht korrekt

  Alt 17. Apr 2018, 14:15
Weil ich bisher nicht wirklich wegwarf, sondern "drüber assignte" hab ich also ein Speicherleck.
Das sollte aber nicht so sein und wenn, dann wäre es ein Bug.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.798 Beiträge
 
Delphi 12 Athens
 
#5

AW: FMX: TBitmap.Assign Methode erscheint mir nicht korrekt

  Alt 17. Apr 2018, 15:04
Ich habe die ganz dufte CopyFromBitmap Methode entdeckt. Damit hat sich der Spuk für mich erledigt. Ich setze die Größe meines Ziels auf die Größe der Quelle und dann führe ich TBitmap.CopyFromBitmap(Source) aus und fertig. Kein Speicherleck mehr.

Wenn ich dann mal Zeit habe, schaue ich mir vielleicht an, was beim Assign falsch laufen könnte, aber jetzt bin ich glücklich. Danke Himitsu, es hilft häufig einfach nur über ein Problem zu reden.

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#6

AW: FMX: TBitmap.Assign Methode erscheint mir nicht korrekt

  Alt 17. Apr 2018, 15:58
Ein Speicherleck oder Bug ist mir an der Stelle nicht bekannt und es funktioniert so wie es soll.

Weder hier
Delphi-Quellcode:
var
  bmp: TBitmap;
begin
  bmp := TBitmap.CreateFromFile('picture.png');
  try
    Image1.Bitmap := bmp;
  finally
    bmp.Free();
  end;
end;
noch da
Delphi-Quellcode:
var
  bmp: TBitmap;
begin
  bmp := TBitmap.CreateFromFile('picture.png');
  try
    Image1.Bitmap.Assign(bmp);
  finally
    bmp.Free();
  end;
end;
passiert etwas Merkwürdiges.

Interessant wäre zu sehen, was du in deinem Code konkret veranstaltest ...
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: FMX: TBitmap.Assign Methode erscheint mir nicht korrekt

  Alt 17. Apr 2018, 16:08
Image1.Bitmap := bmp; und Image1.Bitmap.Assign(bmp); ist das Selbe, siehe dem Setter von .Bitmap

[edit] OK, bei Startet nicht, aber glaub mir einfach, dass der Setter intern das Assign aufruft.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Der schöne Günther

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

AW: FMX: TBitmap.Assign Methode erscheint mir nicht korrekt

  Alt 17. Apr 2018, 16:09
Vor allem wäre die Plattform interessant (also mit ARC oder ohne).
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.798 Beiträge
 
Delphi 12 Athens
 
#9

AW: FMX: TBitmap.Assign Methode erscheint mir nicht korrekt

  Alt 18. Apr 2018, 08:18
Tja, mein Code reicht durch mehrere Ebenen und in mehrere Listen. Ich war überzeugt, alles wird gut aufgeräumt. Und dadurch, daß ich nicht mehr Assign sondern CopyFromBitmap verwende werden mir auch keine Leaks mehr gemeldet. Eventuell habe ich auch einfach nur den Überblick verloren... Dennoch sehen meine eigenen Assign-Methoden anders aus, als das da. Für mich besteht ein Assign darin, zwei vollständig unabhängige Objekte gleichen Inhalts zu erzeugen...Klonen sozusagen. Und das passiert da IMHO nicht. Und den Inhalt eines Objekts zu setzen, daß in der nächsten Zeile durch ein anderes ersetzt wird, finde ich auch komisch.

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#10

AW: FMX: TBitmap.Assign Methode erscheint mir nicht korrekt

  Alt 18. Apr 2018, 08:37
Du meinst dein Assign sieht ungefähr so aus?
Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.Classes,
  System.SysUtils;

type
  TMyClass = class( TPersistent )
  private
    FData: string;
  public
    procedure Assign( Source: TPersistent ); override;
  public
    property Data: string read FData write FData;
  end;

procedure TMyClass.Assign( Source: TPersistent );
begin
  if ( Source is TMyClass ) then
  begin
    FData := TMyClass( Source ).FData;
  end
  else
    inherited;
end;

var
  a, b: TMyClass;

begin
  try
    a := nil;
    b := nil;
    try
      a := TMyClass.Create();
      b := TMyClass.Create();

      a.Data := 'Foo';
      b.Assign(a);
      WriteLn(b.Data);

    finally
      a.Free;
      b.Free;
    end;
  except
    on E: Exception do
      Writeln( E.ClassName, ': ', E.Message );
  end;
end.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 05:41 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