AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi EOutOfResources erzeugt Speicherleck
Thema durchsuchen
Ansicht
Themen-Optionen

EOutOfResources erzeugt Speicherleck

Ein Thema von Schorschi5566 · begonnen am 5. Dez 2010 · letzter Beitrag vom 6. Dez 2010
Antwort Antwort
Seite 1 von 3  1 23      
Schorschi5566

Registriert seit: 6. Feb 2006
197 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#1

EOutOfResources erzeugt Speicherleck

  Alt 5. Dez 2010, 15:03
Hallo DP,

ich programmiere gerade ein Multithreading-Projekt, das sehr große JPGs herunterskaliert und erneut speichert.

Dazu werden bis zu 30 Threads verwendet, die mittlerweile keinerlei Speicher- oder Handle-Leaks mehr verursachen.

Trotzdem kommt es natürlich öfter mal zu EOutOfResources, was auch nicht weiter tragisch ist, da sich dann einige Threads einfach selbst killen und sobald es die Speichersituation wieder zulässt, erneut starten. Das funktioniert bestens soweit.

Einziges Manko ist eigentlich, dass die Exception EOutOfResources selbst ein Memoryleak verursacht, welches ich gerne beheben würde. (siehe Screenshot)

Hat jemand einen Tipp, was man da im Fehlerfall freigeben muss oder ist das ein Bug in Delphi?


Grüße,
Uwe
Miniaturansicht angehängter Grafiken
eoutofresources.jpg  
Uwe
"Real programmers can write assembly code in any language." - Larry Wall
Delphi programming rocks

Geändert von Schorschi5566 ( 5. Dez 2010 um 23:19 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

AW: EOutOfResources erzeugt Speicherleck

  Alt 5. Dez 2010, 15:10
ich programmiere nun schon einige Jahre, aber diese Exception hatte ich noch nie. Ich bin mir ziemlich sicher, dass du irgendwo Ressouren nicht wieder frei gibst.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Schorschi5566

Registriert seit: 6. Feb 2006
197 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#3

AW: EOutOfResources erzeugt Speicherleck

  Alt 5. Dez 2010, 15:24
Wenn 30 Threads versuchen jeweils eine Grafik mit 5000x5000 Punkten in den Speicher zu laden, bekommt man die Meldung recht schnell.

Ich programmiere auch schon einige Jahre und glaube mir, die Routine verliert keine Resourcen.

Am Skalierungsprozess ist allerdings die Library Graphics32 beteiligt, die auch die Exception wirft. Eventuell allokiert ja dort etwas Sachen, die Delphi dann am Schluß anmeckert.

Aber warum schreibt Delphi dann was von x Mal EOutOfResources?
Uwe
"Real programmers can write assembly code in any language." - Larry Wall
Delphi programming rocks
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

AW: EOutOfResources erzeugt Speicherleck

  Alt 5. Dez 2010, 15:29
Wie wäre es die Anzahl der Threads zu reduzieren?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Schorschi5566

Registriert seit: 6. Feb 2006
197 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#5

AW: EOutOfResources erzeugt Speicherleck

  Alt 5. Dez 2010, 15:39
Das passiert schon. Sobald eine EOutOfResources auftritt, beendet sich der entsprechende Thread und macht Luft für die anderen.

Allerdings schwankt das Datenaufkommen und deshalb sollen die Threads wieder erhöht werden, wenn es möglich ist. Nach einer gewissen Zeit werden die Threads also wieder nach und nach gestartet. Bis es wieder knallt.

Funktioniert, wie gesagt ausgezeichnet, mal von dem kleinen Speicherleck abgesehen.

Am Schluss eines Laufs, gibt das Programm eine Empfehlung, wie viele Threads man künftig verwenden sollte aber das behebt das Problem ja nun nicht wirklich.

Du meinst also, dass die Exception an sich keinen Speicher verschludert. Kann natürlich sein, dass TBitmap32.Draw die Exception zu spät wirft und nicht alles freigibt, was bis dahin passiert ist. Werde ich mal erforschen.

Danke schon mal.
Uwe
"Real programmers can write assembly code in any language." - Larry Wall
Delphi programming rocks
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: EOutOfResources erzeugt Speicherleck

  Alt 5. Dez 2010, 15:42
Wenn du schnell was umrechnen willst, dann bringt es sowieso nix, wenn du meh Threads rechnen läßt, als als Recheneinheiten (CPUs/Kerne) vorhanden sind.

PS: 5000x5000 umzurechnen belegt pro Bild schnell mal über 100 MB, da bestimmt über ein Bitmap gerechnet wird, was bei 30 Threads/Bildern wohl etwas viel werden kann.

PSS: Eine Leckprüfung im delphieigenem Speichermanager findet nur Lecks in diesem Teil ... es gibt aber auch noch andere Speichermager und unzählige Handles, welche da nicht mit beachtet werden.
$2B or not $2B

Geändert von himitsu ( 5. Dez 2010 um 15:46 Uhr)
  Mit Zitat antworten Zitat
Schorschi5566

Registriert seit: 6. Feb 2006
197 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#7

AW: EOutOfResources erzeugt Speicherleck

  Alt 5. Dez 2010, 15:45
In diesem Fall bringen 30 gegenüber 10 Threads einen deutlichen Vorteil. Mit den Benchmarks bin ich schon durch.
Uwe
"Real programmers can write assembly code in any language." - Larry Wall
Delphi programming rocks
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: EOutOfResources erzeugt Speicherleck

  Alt 5. Dez 2010, 15:47
In diesem Fall bringen 30 gegenüber 10 Threads einen deutlichen Vorteil. Mit den Benchmarks bin ich schon durch.
Dann ist wohl deine Umrechnung der Bilder nicht sonderlich gut.
$2B or not $2B
  Mit Zitat antworten Zitat
Schorschi5566

Registriert seit: 6. Feb 2006
197 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#9

AW: EOutOfResources erzeugt Speicherleck

  Alt 5. Dez 2010, 15:58
Was hat das mit der Qualität des Downscalingfilters zu tun? (Ist der Lanczos-Filter aus Graphics32. BTW: Hervorragende Qualität)

Das Problem ist doch am Rande des Resourcenlimits zu arbeiten. Wenn ich vor dem Schritt, der die Exception verursacht, wüsste wie viel Speicher benötigt wird, könnte ich es ja abfangen und den Thread schon vorher abknipsen. Das weiß ich aber nicht und genau dazu ist Exceptionhandling doch da, oder?

P.S.: Das Teil verursacht wirklich keine Lecks mehr (mal von dem ganz kleinen abgesehen). Getestet über mehrere Stunden anhand von Taskmanager und Process Explorer. Die Handles nehmen nicht zu und der Speicherverbrauch steigt auch nicht an. Im Moment habe ich allerdings Probleme in Graphics32 die entsprechenden Stellen im Source zu finden, die für das Minileck verantwortlich sein könnten.
Uwe
"Real programmers can write assembly code in any language." - Larry Wall
Delphi programming rocks

Geändert von Schorschi5566 ( 5. Dez 2010 um 16:10 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von littleDave
littleDave

Registriert seit: 27. Apr 2006
Ort: München
556 Beiträge
 
Delphi 7 Professional
 
#10

AW: EOutOfResources erzeugt Speicherleck

  Alt 5. Dez 2010, 16:21
Die Exception EOutOfResources ist eine besondere Exception, da sie von der EOutOfMemory - Exception abgeleitet wird. Erstell mal ein Test-Projekt, binde FastMM ein und auf die Form1 klatscht du ein Button drauf. Im Click-Handler schreibst du folgendes:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  raise EOutOfResources.Create('bla bla blub');
end;
Dann starte das Testprogramm, klick den Button und beende das Programm: und siehe da: EOutOfResources wird nicht freigegeben. Wenn du jetzt irgend eine andere beliebige Exception (außer EOutOfMemory) benutzt, wird diese korrekt freigegeben.

Exceptions, die von EOutOfMemory abgeleitet sind, dürfen also nicht so geworfen werden. Für die EOutOfMemory gibt es in der SysUtils-Unit die Funktion OutOfMemoryError , ob es das für EOutOfResources auch gibt, weiß ich nicht.

Die Ausnahme ist sehr sinnvoll: wenn kein Speicherplatz mehr vorhanden ist, soll ja diese Exception geworfen werden. Blöd wäre jetzt nur, wenn für die Exception auch kein Speicher mehr vorhanden wäre. Daher wird eine Instanz der Exception global beim Start angelegt und diese Instanz wird einfach immer wieder neu geworfen.

[Ergänzung]
Mal ein Auszug aus der Delphi-Hilfe für EHeapException:
Zitat:
Die von EHeapException abgeleiteten Klassen EOutOfMemory und EInvalidPointer werden dazu verwendet, fehlgeschlagene Zuweisungen von dynamischem Speicher und ungültige Zeigeroperationen abzufangen.

Hinweis: Speicher für diese Exceptions wird im Voraus zugewiesen, sobald eine Anwendung startet. Die Zuweisung bleibt bestehen, solange die Anwendung läuft. EHeapException oder Nachkommen davon dürfen niemals direkt ausgelöst werden.
Jabber: littleDave@jabber.org
in case of 1 is 0 do external raise while in public class of object array else repeat until 1 is 0

Geändert von littleDave ( 5. Dez 2010 um 16:32 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 03:23 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