![]() |
EOutOfRessources bei vielen Bitmap-Operationen
Hallo zusammen,
In meinem Programm wird ein MJpeg-Stream ausgelesen und jedes einzelne Bild hintereinander in ein Bitmap kopiert. Nach etwa 3 Stunden Laufzeit bekomme ich nur noch EOutOfResources-Exceptions. So sieht die Funktion aus, die meine Bitmaps füttert:
Delphi-Quellcode:
In der Zeile mit dem Assign meldet mir MemProof
procedure TMJPEGThread.GenerateBitmap;
var JPEGImage: TJPEGImage; begin JPEGImage := TJPEGImage.Create; try JPEGImage.LoadFromStream(FAktImg); JPEGImage.Performance := jpBestSpeed; FBitmap.Assign(JPEGImage); ImgReady(FBitmap); finally JPEGImage.Free end; end; Zitat:
Ich hab versucht FBitmap.FreeImage aufzurufen, bevor das neue Bild zugewiesen wird, dass ändert aber nix an den Meldungen von MemProof. Was mach ich falsch? grüße, daniel [EDIT]Hatte nur die hälfte von der Memproof-Meldung kopiert.[/EDIT] |
Re: EOutOfRessources bei vielen Bitmap-Operationen
Hallo Daniel,
ich vermisse in deinem Code die Bitmap-Methoden Dormant(), FreeImage(), ReleaseHandle(), was allerdings auch daran liegen könnte, dass du die an anderer Stelle verwendest. Sobald du keinen Bedarf mehr für die Original-Bildparameter hast, sind die angesagt. Grüße vom marabu |
Re: EOutOfRessources bei vielen Bitmap-Operationen
Moin!
Zitat:
MfG Muetze1 |
Re: EOutOfRessources bei vielen Bitmap-Operationen
Hallo Marabu,
Ich hab jetzt mal die Funktion so angepasst:
Delphi-Quellcode:
MemProof meldet das gleiche Problem noch in der Funktion ImgReady und zwar beim Aufruf eines Events, dem diese Funktion zugewiesen ist:
procedure TMJPEGThread.GenerateBitmap;
var JPEGImage: TJPEGImage; begin JPEGImage := TJPEGImage.Create; try JPEGImage.LoadFromStream(FAktImg); JPEGImage.Performance := jpBestSpeed; FBitmap.Assign(JPEGImage); ImgReady(FBitmap); finally FBitmap.Dormant; FBitmap.FreeImage; FBitmap.ReleaseHandle; JPEGImage.Free end; end;
Delphi-Quellcode:
Weil FBitmap das OffScreen-Bitmap für eine PaintBox ist, kann ich Dormant und Co. erst vor dem nächsten Zuweisen aufrufen.
procedure TAnzeige.OnImage(Sender: TObject; _Img: TBitmap);
begin if Assigned(FCritSect) then begin FCritSect.Acquire; try if not FLocked then begin if not FBitmap.Empty then begin FBitmap.Dormant; // Free up GDI resources FBitmap.FreeImage; // Free up Memory. (not really needed) FBitmap.ReleaseHandle; // This will actually lose the bitmap (not needed) end; FBitmap.Assign(_Img); end; finally FCritSect.Leave; end; if GetTickCount >= (FLastImgRefresh + FMinImgRefresh) then begin //PostMessage(self.Handle, WM_PAINT, 0, 0); FFestImgReady := true; (sender as TImgThread).DoSynchronize(pbImg.Invalidate); FLastImgRefresh := GetTickCount; end; end; end; MemProof zeigt mir übrigens immer jeweils einen Fehler beim Aufruf von GenerateBitmap und einen beim Aufruf dieses Events an. [Nachtrag zum Posting von Muetze] Heißt das für mich, ich sollte einfach mit FreeImage und ReleaseHandle aufräumen? |
Re: EOutOfRessources bei vielen Bitmap-Operationen
Ich hab gerade bemerkt, dass GenerateBitmap in dieser Form:
Delphi-Quellcode:
innerhalb von ca. 1 Minute satte 350MB Speicher frisst.
procedure TMJPEGThread.GenerateBitmap;
var JPEGImage: TJPEGImage; begin JPEGImage := TJPEGImage.Create; try JPEGImage.LoadFromStream(FAktImg); JPEGImage.Performance := jpBestSpeed; FBitmap.Assign(JPEGImage); ImgReady(FBitmap); finally FBitmap.Dormant; FBitmap.FreeImage; FBitmap.ReleaseHandle; JPEGImage.Free end; end; Wenn ich ReleaseHandle auskommentiere, ist der Speicherverbrauch gestoppt. Ich werds mal versuchen, nur mit FreeImage laufen zu lassen. |
Re: EOutOfRessources bei vielen Bitmap-Operationen
Hola Sanchez,
ich bin kein Grafikspezialist, also nur zum Abgleich unseres Verständnisses von TBitmap... Mit LoadFrom...() wird ein lossless image von der externen Bitmap-Datei im Speicher erzeugt. Sobald du an dem Bild rumspielst, wird eine Kopie davon erzeugt - dabei wird die Farbtiefe auf 16 reduziert. Statt Rumspielen kannst du das Kopieren auch mit Dormant() erzwingen. Der Schlafmodus bezieht sich dabei offenbar auf das lossless image. Der Verbrauch von GDI-Resourcen wird dabei verringert, aber der Speicherbedarf kann steigen. Mit FreeImage() kannst du den Speicher des dormant image freigeben. Mit ReleaseHandle() werden handle und image voneinander getrennt, z.B. zwecks Freigabe des Handles mit DeleteObject(). Wenn alle deine Arbeiten mit dem Bitmap beendet sind, dann solltest du nach meiner Meinung das klassische Free() aufrufen, bevor du mit Assign() zum nächsten Bild gehst. Vielleicht habe ich dich mit meinem unbedachten Hinweis auf die vielen bunten Methoden aus dem Delphi OH Beispiel ein wenig in die falsche Richtung gejagt... vaja con dios Zerknirschte Grüße vom marabu |
Re: EOutOfRessources bei vielen Bitmap-Operationen
Oiga marabu,
Ich hab jetzt mal einen Versuch gemacht, bei dem ich mir für jedes Assign eine eigene Bitmap-Instanz erzeuge und am Ende wieder freigebe. Dadurch werden die GDI-Ressourcen aber trotzdem verbraten. Allerdings bei weitem nicht bei jedem Durchlauf. So ca. jede Minute geht ein Handle verloren. Es werden aber in der Sekunde vermutlich min. 50 Bitmaps zugewiesen. Ich werd aus dem ganzen nicht schlau. grüße, daniel |
Re: EOutOfRessources bei vielen Bitmap-Operationen
Was passiert denn, wenn du das JPEGImage nicht immer neu erstellst, sondern eine private-Feld deines Threads draus machst, das beim Formcreate (oder so) erstellst und beim Formdestroy freigibst?
|
Re: EOutOfRessources bei vielen Bitmap-Operationen
Hi,
Das ändert gar nichts. Mir ist übrigens gerade aufgefallen, dass laut MemProof auch der Aufruf einer Funktion, die von zwei Bitmaps die Scanlines durchmarschiert und in eines davon reinpinselt, gelegentlich GDI-Ressource schluckt. Kann mir jemand erklären warum und was ich dagegen machen könnte? |
Re: EOutOfRessources bei vielen Bitmap-Operationen
Das Problem hab ich jetzt weitgehend im Griff.
Das Problem waren die Massen an Assigns die ich Kreuz und Quer ausgeführt hab. Die hab ich jetzt teilweise durch BitBlts ersetzt und nach etwas Spielerei meldet Memproof keine vernichteten GDI-Ressourcen mehr. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz