AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Systemressourcen erschöpft beim VirtualStringTree.AfterCellPaint
Thema durchsuchen
Ansicht
Themen-Optionen

Systemressourcen erschöpft beim VirtualStringTree.AfterCellPaint

Ein Thema von Hobbycoder · begonnen am 15. Nov 2018 · letzter Beitrag vom 17. Nov 2018
Antwort Antwort
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.493 Beiträge
 
Delphi 12 Athens
 
#1

AW: Systemressourcen erschöpft beim VirtualStringTree.AfterCellPaint

  Alt 16. Nov 2018, 08:33
In vstTermineAfterCellPaint wird eine bmp-Variable verwendet, die nicht lokal deklariert ist.
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.277 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Systemressourcen erschöpft beim VirtualStringTree.AfterCellPaint

  Alt 16. Nov 2018, 08:42
Hallo,
zumindestens wird ja was angezeigt, aber leider keine Bitmaps.
Die "Ausrede", Projekt ist zu gross, lasse ich nicht gelten

Du kannst es ja abspecken (schrittweise ausklammern).

FastMM4 würde dir die Zeile zeigen, wo die jeweilige Klasse erzeugt wird, die nicht freigegeben wird.
Was schon mal komisch ist, dass er 2 Connections anzeigt.
Kann es sein, das Du deine globale Connection beim Programmende nicht freigibst?

Breakpoint auf destructor TDBAccess.Destroy; setzen und nachschauen
Heiko

Geändert von hoika (16. Nov 2018 um 09:27 Uhr)
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Systemressourcen erschöpft beim VirtualStringTree.AfterCellPaint

  Alt 16. Nov 2018, 09:08
Die zwei Connections wundern mich auch etwas. Das sollte eigentlich schon die Ursache für die ganzen nachfolgenden Memory Leaks sein.


Aber zurück zur eigentlichen Frage:

Kompiliert denn der SourceCode so überhaupt wie du ihn hier geschrieben hast? Mir fehlt zu dem zweiten try ein except .

Delphi-Quellcode:
      11: begin
          if t.RTFTextList.Items(ttArbeiten)<>Nil then
          begin
            top:=Trunc((CellRect.Height-t.RTFTextList.Items(ttArbeiten).pic.Bitmap.Height)/2);
            BitBlt(TargetCanvas.Handle, CellRect.Left, CellRect.Top+top, CellRect.Width, CellRect.Height, t.RTFTextList.Items(ttArbeiten).pic.Bitmap.Canvas.Handle, 0, 0, SRCAND); //<---- Manchmal aber auch hier
          end;
          bmp:=TBitmap.Create;
          bmp.Height:=ilInformation.Height;
          bmp.Width:=0;
          try
          try
            if t.TB then AddSymbol(SymTB, '', bmp);
            if t.TD then AddSymbol(SymTD, '', bmp);
            if t.FD then AddSymbol(SymFD, '', bmp);
            if t.HB then AddSymbol(SymHB, '', bmp);
            if t.PlainTextList.Items(ttBemerkung)<>nil then
              if t.PlainTextList.Items(ttBemerkung).text<>'then
                AddSymbol(SymBemerkung, '', bmp);
            if t.REgeschrieben then AddSymbol(SymRE, '', bmp);
            if t.dmsAuftragNr<>'then AddSymbol(SymAB, '', bmp);
            top:=Trunc((CellRect.Height-bmp.Height)/2);
            BitBlt(TargetCanvas.Handle, CellRect.Left+CellRect.Width-bmp.Width, CellRect.Top+top, bmp.Width, bmp.Height, bmp.Canvas.Handle, 0, 0, SRCCOPY);
          finally
            bmp.Free;
          end;
        end;


Dinge die du mal noch ausprobieren kannst:

Dann würde ich an deiner Stelle mal Teile der Paint Procedure auskommentieren und schauen, ob der Fehler immer noch auftritt.
Erkennst du den Fehler nur daran, dass die CPU Auslastung nach oben geht? Oder läuft dein RAM irgendwann voll? Kannst du mal testen was passiert, wenn du die AddSymbol Procedure direkt integrierst und das Kopieren des Bitmaps in den var Parameter auslässt und stattdessen direkt auf das Canvas malst?
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.375 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Systemressourcen erschöpft beim VirtualStringTree.AfterCellPaint

  Alt 16. Nov 2018, 09:46
Was schon mal komisch ist, dass er 2 Connections anzeigt.
Ich habe mir mal die Doku zu Klassen-Konstruktoren angesehen.
Wenn die korrekt ist, wundert mich das nicht.

Klassen-Konstruktoren werden bei Bedarf automatisch ausgeführt.
Aber in dieser Klasse wird der Klassen-Konstruktor nochmal manuell aufgerufen. Die Folge sind dann offensichtlich zwei Connections.

Ich habe mit Klassen-Konstruktoren noch nicht gearbeitet und komme nur durch die Delphi-Doku auf diese Idee.
http://docwiki.embarcadero.com/RADSt...nkonstruktoren
Peter
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
1.017 Beiträge
 
#5

AW: Systemressourcen erschöpft beim VirtualStringTree.AfterCellPaint

  Alt 17. Nov 2018, 14:15
Ich bin jetzt ein kleines Stück weiter. Habe mal alles deaktiviert, alle Threads, so dass am Ende nur der Mainthread über bleibt. Sprich die DB wird geöffnet und bei Programmende wieder geschlossen, ohne dass DB-Abfragen dazwischen laufen. Ergebnis: Keine MemoryLeaks.

Jetzt fange ich an, alles Stück für Stück wieder zu aktivieren, und teste jedes Mal ob und wo ein MemoryLeak auftritt.
Ich bin auch gleich fündig geworden in folgende Methode:

Delphi-Quellcode:
procedure TStamminfos.LoadFromDBByRev(Con: TUniConnection; Betriebguid,
  Refguid: TGUID; Ref: string);
var
  q: TUniQuery;
begin
  q:=TUniQuery.Create(nil);
  try
    q.Connection:=Con;
    if not Con.Connected then exit;
    q.SQL.Text:='Select * from stamminfos where betriebguid=:betriebguid and (Refguid=:refguid or ref=:ref)';
    q.Params.ParamValues['betriebguid']:=Betriebguid.ToString;
    q.Params.ParamValues['Refguid']:=Refguid.ToString;
    q.Params.ParamValues['Ref']:=Ref;
    q.Active:=True;
    if q.RecordCount>0 then
    begin
      Self.ID:=q.FieldByName('ID').AsInteger;
      Self.guid:=StringToGUID(q.FieldByName('guid').AsString);
      Self.betriebguid:=StringToGUID(q.FieldByName('betriebguid').AsString);
      Self.Refguid:=StringToGUID(q.FieldByName('Refguid').AsString);
      Self.Ref:=q.FieldByName('Ref').AsString;
      Self.RTFText.Position:=0;
      (q.FieldByName('RTFText') as TBlobField).SaveToStream(Self.RTFText); //<<--Hier muss der Übeltäter liefen.
      Self.RTFText.Position:=0;
      Self.Text:=q.FieldByName('Text').AsString;
      Self.Level:=TInfosLevel(q.FieldByName('Level').AsInteger);
    end;
    q.active:=False
  finally
    q.Free;
  end;
end;
Kommentiere ich die Zeile SaveToStream aus, so habe ich kein MemoryLeak. Lass ich sie mit ausführe, habe ich ein MemoryLeak.

Ist das Auslesen eines BlobFields denn so falsch? (Self.RTFText ist TMemoryStream, welches auch korrekt erzeugt und freigegeben wird).
Gibt es noch eine andere (bessere) Möglichkeit den Inhalt von BlobFiels auszulesen? Ich kenn nur die.

PS: Die o.g. Methode läuft in einem Thread, der seine eigene Connection hat.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
1.017 Beiträge
 
#6

AW: Systemressourcen erschöpft beim VirtualStringTree.AfterCellPaint

  Alt 16. Nov 2018, 09:18
In vstTermineAfterCellPaint wird eine bmp-Variable verwendet, die nicht lokal deklariert ist.
Oh, ja, sorry, ich hatte die Funktion leicht gekürzt (einige Case rausgeschissen). und damit es nicht verwirrt auch die Var-Declarationen, die mit dem Fehler nicht zu tun haben können.
Tatsächlich wird die bmp lokal deklariert. (Hab das oben korrigiert)

Hallo,
zumindestens wird ja was angezeigt, aber leider keine Bitmaps.
Doch. Der Fehler tritt ja nicht immer auf. Die Bitmap sehe ich im VST. Und ich kann auch nicht sagen, dass mir da was fehlt, wenn ich im MADExcept auf Continue Klicke. Zur Zeit habe ich das Gefühl, dass mehr Zeile den Fehler eher auftreten lassen. Das ist aber nur gefühlt. Ich bin gerade dabei, das ganze mal so zu ändern, dass ich nur mit 2-3 Zeilen arbeiten kann.

Die "Ausrede", Projekt ist zu gross, lasse ich nicht gelten

Du kannst es ja abspecken (schrittweise ausklammern).
Darauf wird wohl hinauslaufen. Wahrscheinlich muss ich noch back to the roots, und mir das mit der Connection / Globalen Klasse noch mal genau anschauen. Ich glaube fast das da im Constructor/Destructor irgendwas im argen liegt.

FastMM4 würde dir die Zeile zeigen, wo die jeweilige Klasse erzeugt wird, die nicht freigegeben wird.
Was schon mal komisch ist, dass er 2 Connections anzeigt.
Kann es sein, das Du deine globale Connection beim Programmende nicht freigibst?
FastMM werde ich auch noch mal ausprobieren.
Also im Mainthread verwende ich definitiv nur 1 Connection. Ich muss mal die Threads deaktivieren. Möglicherweise stammt die zweite Connection ja von einem der Threads (die eigentlich alle vor Programmende korrekt beendet werden).

Die zwei Connections wundern mich auch etwas. Das sollte eigentlich schon die Ursache für die ganzen nachfolgenden Memory Leaks sein.


Aber zurück zur eigentlichen Frage:

Kompiliert denn der SourceCode so überhaupt wie du ihn hier geschrieben hast? Mir fehlt zu dem zweiten try ein except .
Das war ein Fehler beim zusammen kopieren. Es gibt nur ein Try. Ich hatte die Methode wie oben bereits erwähnt etwas eingekürzt, dass die restlichen Case-Fälle mit dem Fehler nichts zu tun haben können. Zwar wird auch da gezeichnet, aber nur in dieser Spalte tritt der Fehler auf. Das hatte ich durch Auskommentieren bereits getestet.

Dinge die du mal noch ausprobieren kannst:

Dann würde ich an deiner Stelle mal Teile der Paint Procedure auskommentieren und schauen, ob der Fehler immer noch auftritt.
Erkennst du den Fehler nur daran, dass die CPU Auslastung nach oben geht? Oder läuft dein RAM irgendwann voll? Kannst du mal testen was passiert, wenn du die AddSymbol Procedure direkt integrierst und das Kopieren des Bitmaps in den var Parameter auslässt und stattdessen direkt auf das Canvas malst?
Auskommentieren habe ich bereits gemacht und somit auf diese Spalte reduziert. CPU-Auslastung ist normal 3-5 % und auch Ram wird nicht soviel belegt, dass es jetzt irgendwie auffällig wäre. Aber ich werde mal die AddSymbol-Methode ganz auskommentieren und mal schauen was sich verändert.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Antwort Antwort


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 15:38 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-2025 by Thomas Breitkreuz