![]() |
AW: Memory Leak nach Zuweisung eines Resourcestream
Ob in die EXE oder in eine DLL macht technisch keinen Unterschied. Man braucht nur das Handle des entsprechenden Moduls.
in Delphi ist HInstance das Handle der EXE/DLL, wo der Code drin ist. (aufpassen, wenn mit Packages compiliert) ![]() ![]() ![]() |
AW: Memory Leak nach Zuweisung eines Resourcestream
noch mal vielen Dank,
der Link zum SVG ist sehr wertvoll |
AW: Memory Leak nach Zuweisung eines Resourcestream
Also ich mache das schon immer so...
Ich packe alle Resourcen per zlib und binde diese ein... Ob in einer DLL oder in der Exe ist fast egal, es sei den, Du brauchst die Speicherkachel von ~2GB (3GB mit flag) voll und ganz für die exe... Mavarik |
AW: Memory Leak nach Zuweisung eines Resourcestream
Also eine Resourcen DLL ist so ziemlich das Dümmste was du machen kannst. Ausser dass du deutlich mehr Aufwand hast (2 Projektet die jeweils kompiliert werden, 2 Dateien die ausgeleifert werden müssen, etc.) bringt das überhaupt keine Voreteile. Du kannst die Bilder problemlos in deine EXE linken. Die Resoucen werden erst geladen, wenn du sie explizit lädst. Also mit Resourcensparen hat das nichts zu tun.
|
AW: Memory Leak nach Zuweisung eines Resourcestream
Zitat:
Die Resourcen sind immer da... Vielleicht verwechselst Du das mit den Resourcen die dann oben drauf nochmal für die Bilder benötigt werden... Natürlich macht es Sinn Resourcen in eine DLL auszulagern... 1.) DLL Laden 2.) Resourcen extrahieren 3.) DLL wieder aus dem Speicher werfen... Somit bleibt fürs Hauptprogramm wieder der volle Speichern. |
AW: Memory Leak nach Zuweisung eines Resourcestream
Hallo Mavarik,
habe ich Dich richtig verstanden, Du bindest alle Bilder (png, jepeg ua) in eine Zip-Datei und holst sie dann bei Bedarf aus der Datei? Das ist vermutlich hinsichtlich benötigten Speicherplatzes auf der HDU die beste Variante. Gruß Peter |
AW: Memory Leak nach Zuweisung eines Resourcestream
@Mavarik / Rolf Frei:
Jupp, länger "ungenutzter" Speicher kann von Windows aus dem RAM (ühysischer Speicher) geworfen werden, aber im virtuellen Programmspeicher bleibt es dennoch vorhanden und belegt ihn (bei 32-Bit sind die normalen 2GB schnell voll) Resourcen-DLL wieder entladen, macht auch da den Platz wieder frei. |
AW: Memory Leak nach Zuweisung eines Resourcestream
Zitat:
Disclaimer: Das Beispiel ist ein Proof of Concept, der Sourcecode ist weder getestet noch optimiert.
Delphi-Quellcode:
Anwenden kannst du es so:
uses
mormot.core.base, mormot.core.data, mormot.core.text, mormot.core.os, mormot.core.zip, mormot.core.perf, mormot.crypt.core; type TImageResourceFile = class(TObject) private FPassword: RawUtf8; FFileName: TFileName; FIsWritable: Boolean; protected function LoadStream(pmStream: TCustomMemoryStream; const pmcResName: TFileName; const pmcPassword: RawUtf8): Boolean; procedure SaveStream(pmStream: TCustomMemoryStream; const pmcResName: TFileName; const pmcPassword: RawUtf8; pmIsCompressed: Boolean = True); public constructor Create(const pmcFileName: TFileName; const pmcPassword: RawUtf8); destructor Destroy; override; function LoadImage(pmImage: TImage; const pmcImageName: String): Boolean; procedure SaveImage(pmImage: TImage; const pmcImageName: String); overload; procedure SaveImage(pmImageData: TCustomMemoryStream; const pmcImageName: String); overload; end; constructor TImageResourceFile.Create(const pmcFileName: TFileName; const pmcPassword: RawUtf8); begin inherited Create; FFileName := pmcFileName; FPassword := pmcPassword; FIsWritable := IsDirectoryWritable(ExtractFilePath(FFileName)); end; destructor TImageResourceFile.Destroy; begin FillZero(FPassword); inherited Destroy; end; function TImageResourceFile.LoadStream(pmStream: TCustomMemoryStream; const pmcResName: TFileName; const pmcPassword: RawUtf8): Boolean; var idx: Integer; zipRead: TZipRead; encStream: TMemoryStream; aesReader: TAesPkcs7Reader; begin Result := False; if pmStream = Nil then Exit; //=> if pmcResName = '' then Exit; //=> if not FileExists(FFileName) then Exit; //=> zipRead := TZipRead.Create(FFileName); try idx := zipRead.NameToIndex(pmcResName); if idx < 0 then Exit; //=> if pmcPassword = '' then Result := zipRead.UnZip(idx, pmStream) else begin encStream := TMemoryStream.Create; try if zipRead.UnZip(idx, encStream) then begin encStream.Position := 0; aesReader := TAesPkcs7Reader.Create(encStream, pmcPassword); try Result := (StreamCopyUntilEnd(aesReader, pmStream) > 0); finally aesReader.Free; end; end; finally encStream.Free; end; end; finally zipRead.Free; end; end; procedure TImageResourceFile.SaveStream(pmStream: TCustomMemoryStream; const pmcResName: TFileName; const pmcPassword: RawUtf8; pmIsCompressed: Boolean); const IS_COMPRESSED: array[Boolean] of Integer = (0, 6); var zipWrite: TZipWrite; encStream: TMemoryStream; aesWriter: TAesPkcs7Writer; begin if pmStream = Nil then Exit; //=> if pmcResName = '' then Exit; //=> if not FIsWritable then Exit; //=> if FileExists(FFileName) then zipWrite := TZipWrite.CreateFromIgnore(FFileName, [pmcResName]) else zipWrite := TZipWrite.Create(FFileName); try if pmcPassword = '' then zipWrite.AddDeflated(pmcResName, pmStream.Memory, pmStream.Size, IS_COMPRESSED[pmIsCompressed], DateTimeToFileDate(Now)) else begin encStream := TMemoryStream.Create; try aesWriter := TAesPkcs7Writer.Create(encStream, pmcPassword); try pmStream.Position := 0; StreamCopyUntilEnd(pmStream, aesWriter); aesWriter.Finish; finally aesWriter.Free; end; zipWrite.AddDeflated(pmcResName, encStream.Memory, encStream.Position, IS_COMPRESSED[pmIsCompressed], DateTimeToFileDate(Now)); finally encStream.Free; end; end; finally zipWrite.Free; end; end; function TImageResourceFile.LoadImage(pmImage: TImage; const pmcImageName: String): Boolean; var tmpStream: TMemoryStream; begin Result := False; if pmImage = Nil then Exit; //=> if pmcImageName = '' then Exit; //=> tmpStream := TMemoryStream.Create; try if LoadStream(tmpStream, pmcImageName, FPassword) then begin tmpStream.Position := 0; try pmImage.Picture.LoadFromStream(tmpStream); Result := True; except end; end; finally tmpStream.Free; end; end; procedure TImageResourceFile.SaveImage(pmImage: TImage; const pmcImageName: String); var tmpStream: TMemoryStream; begin if pmImage = Nil then Exit; //=> if pmcImageName = '' then Exit; //=> tmpStream := TMemoryStream.Create; try pmImage.Picture.SaveToStream(tmpStream); SaveImage(tmpStream, pmcImageName); finally tmpStream.Free; end; end; procedure TImageResourceFile.SaveImage(pmImageData: TCustomMemoryStream; const pmcImageName: String); begin if pmImageData = Nil then Exit; //=> if pmcImageName = '' then Exit; //=> SaveStream(pmImageData, pmcImageName, FPassword, False); end;
Delphi-Quellcode:
Eine 2MB große AES verschlüsselte PNG Bilddatei aus einer Zip-Datei in ein Image laden, benötigt im Beispiele eine Gesamtladezeit von ca. 60 ms. Das ist ein brauchbarer Wert. Davon dauert die Entschlüsselung ca. 5 ms. Wenn du viele Bilder auf einmal schreiben willst, solltest du dir eine BatchAdd Funktion schreiben.
var
timer: TPrecisionTimer; imgResFile: TImageResourceFile; begin Image.Picture.Assign(Nil); timer.Start; imgResFile := TImageResourceFile.Create(ChangeFileExt(Application.ExeName, '.dat'), 'Thomas'); try imgResFile.LoadImage(Image, 'ImageName'); ShowMessage(Format('Total time: %s', [timer.Stop])); finally imgResFile.Free; end; end; mORMot musst du nicht installierten. Es reicht aus, die entsprechenden Bibliothekspfade einzufügen. Es steht eine ausführliche ![]() ![]() Bei einer neuen Anwendung würde ich mORMot2 empfehlen. Dazu gibt es zur Zeit noch keine Hilfe. Trotzdem hier der Link zum ![]() Bis bald... Thomas |
AW: Memory Leak nach Zuweisung eines Resourcestream
Interessanter Nachtrag: Wenn man anstelle der Vcl.Imaging.pngimage besser die mormot.ui.gdiplus Unit verwendet, verkürzt sich das Speichern eines 2MB großen PNG-Bildes mit SaveImage() auf 9 ms gegenüber 900 ms mit der Delphi Unit und ein LoadImage() wird in 10 ms anstatt 80 ms ausgeführt. Es lohnt sich, habe auch nichts anderes erwartet.
Bis bald... Thomas |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:39 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