Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Ursache für dauerhafte CPU-Auslastung finden (https://www.delphipraxis.net/206912-ursache-fuer-dauerhafte-cpu-auslastung-finden.html)

CodeX 8. Feb 2021 17:12

Ursache für dauerhafte CPU-Auslastung finden
 
Ich habe hier ein relativ großes Delphi-Projekt vor mir, wo das Programm minimiert im Tray ohne jegliche Aufgabe eine dauerhafte CPU-Auslastung von 0,1% - 0,2% im Task-Manager anzeigt (andere im Hintergrund laufenden Anwendungen haben 0%). Das mag erstmal nicht schlimm erscheinen, aber normalerweise ist das ein Zeichen dafür, dass irgendetwas nicht passt und dann an anderer Stelle Probleme machen könnte.

Ich frage mich nun, wie ich die Ursache herausfinden kann.
  • Zunächst habe ich es mir mit dem Process Explorer angeschaut. Dort sehe ich mehrere Threads der Anwendung.
  • Der Thread mit der niedrigsten TID (Hauptthread?) schwankt durchgehend zwischen 0.10 und 0.22 herum.
  • In der "Start Address" Spalte steht Name.exe!TMethodImplementationIntercept+0x... Was ist das?
  • Der Stack für diesen Thread zeigt zwar eine Liste mit 27 Einträgen an, aber diese beziehen sich mit Ausnahme des genannten Eintrags auf Windowskomponenten, sodass ich dadurch auch nicht schlauer werde.
  • Im Debugger sehe ich im Threads-Tab alle Threads, die auch im Process Explorer angezeigt wurden, also auch den betroffenen Thread, aber scheinbar kann man dort nichts damit machen (State: Runnable; Status: [leer]).
Wie komme ich jetzt weiter? Kann ich in der IDE irgendwie einen besseren Stack Trace als per Process Explorer anzeigen lassen? Sowas wie madExcept nach einer Exception anzeigt, nur eben im laufenden Betrieb ohne Fehler?
Oder komme ich irgendwie anders weiter?

himitsu 8. Feb 2021 17:17

AW: Ursache für dauerhafte CPU-Auslastung finden
 
AQTime?



Ein Thread hat auch einen Parent-Thread.
Ich glaub der PE sollte dazu auch was anzeigen.

Mit etwas Glück wurde auch der Stacktrace beim Erstellen des Threads gespeichert, so sieht man dann wer den Thread erstellt hat und bekommt so die Antwort wofür der Thread sein soll.

Sinspin 9. Feb 2021 07:30

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Hallo, das ist mir auch schon aufgefallen. Ging vor gut einem Monat los. Ich denke ein Windowsupdate oder der Windows Defender sind schuld an der höheren CPU last. Es sind auch nicht nur Delphi Programme betroffen.

Für...
Zitat:

Zitat von CodeX (Beitrag 1482530)
  • In der "Start Address" Spalte steht Name.exe!TMethodImplementationIntercept+0x... Was ist das?

...hilft erstmal Tante Google weiter. Da gibt es ein paar interessante Infos, die bisher beste ist aus meiner Sicht:
unwanted-export-tmethodimplementationintercept

CodeX 9. Feb 2021 10:00

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von himitsu (Beitrag 1482531)
AQTime?

Vermutlich könnte mir das weiterhelfen. Habe jetzt ein bisschen was dazu nachgelesen und ein Video bei YT angeschaut. Im GetIt sind 262 Pakete vorhanden, aber AQTime ist nicht darunter. Bei den Embarcadero Downloads finde ich nur Versionen für Delphi bis XE8.
Wo kriege ich denn eine funktionierende Standard Version für 10.3 her?

Zitat:

Zitat von himitsu (Beitrag 1482531)
Ein Thread hat auch einen Parent-Thread.

So wie ich das deute, handelt es sich ja um den Main-Thread, also um das Hauptprogramm an sich.

Zitat:

Zitat von Sinspin (Beitrag 1482553)
...hilft erstmal Tante Google weiter. Da gibt es ein paar interessante Infos, die bisher beste ist aus meiner Sicht:
unwanted-export-tmethodimplementationintercept

Ich habe natürlich als erstes danach gesucht, aber es schien mir eher eine generische Fehlerquelle zu sein, also dachte ich, die aus etwas Anderem resultiert. Da ich bei meiner Recherche auch Rtti als Stichwort gefunden habe, habe ich auch geschaut, ob ich hier etwas in der Richtung im Projekt anpassen kann. Da Rtti in dem Projekt gänzlich unerwünscht ist und das Programm nur unnötig aufbläht, wurde es soweit es ging aus dem Projekt entfernt. Da dies ja leider nicht mehr zentral geht, ist in jeder Unit ein Include von diesem Code enthalten:
Delphi-Quellcode:
{$WEAKLINKRTTI ON}
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
Wenn man es irgendwie noch besser und komplett entfernen könnte, bitte sagen!
Ich habe den Teil dann testweise auskommentiert und neu kompelliert, um auszuschließen, dass genau dieses Entfernen etwas damit zu tun hat, aber das CPU-Ergebnis war das gleiche. Lediglich die Exe ist um 10% angewachsen.

Deine verlinkten Infos sind sehr interessant, aber ich weiß nicht, ob mich das weiterbringt:
Ich kann nicht auf eine Delphi-Version vor XE5 wechseln und es handelt sich bei mir nicht um eine DLL.
System.Rtti wird im Projekt nirgends eingebunden. Wahrscheinlich durch irgendeine andere System-Unit oder Komponente.
Die einzige dort empfohlene Option wäre, die System.Rtti zu bearbeiten und den TMethodImplementationIntercept Teil (oder nur die exports Zeile?) auszukommentieren. Das erscheint mir ein bisschen wie mit der Brechstange. Gibt es vielleicht noch irgendeinen anderen Ansatz? Wenn wirklich Rtti Schuld ist, dann Rtti irgendwie komplett aus dem Projekt verbannen?

venice2 9. Feb 2021 10:36

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Darf deine Anwendung auch etwas tun?
0,1% - 0,2% ist doch gar nichts.
Deshalb nach einen angeblichen Fehler zu suchen ist etwas suspekt.
just my 2 cent!

CodeX 9. Feb 2021 12:54

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von venice2 (Beitrag 1482573)
Darf deine Anwendung auch etwas tun?
0,1% - 0,2% ist doch gar nichts.
Deshalb nach einen angeblichen Fehler zu suchen ist etwas suspekt.
just my 2 cent!

Wenn die Anwendung etwas tun soll, dann darf sie das auch. Hier tut sie im minimierten Zustand aber nichts.

Wenn das jeder Prozess im Hintergrund so tun würde, dann wäre die CPU dauerhaft ausgelastet. Alle anderen inaktiven (Hintergrund-)Prozesse sind ja konstant bei 0%. Warum dann meiner nicht? Warum ist das ein "angeblicher" Fehler? Eine Anwendung, die nichts tut und nicht sichtbar ist, darf nicht dauerhaft CPU-Leistung fordern.

Zudem musst Du bedenken, dass die Angabe 0,2% bei (in meinem Fall) 8 Kernen und damit 16 logischen Prozessoren, einen davon zu 3,2% auslastet. Ohne etwas zu tun wohlgemerkt.

Rolf Frei 9. Feb 2021 13:21

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Irgendwo hast du ja einen "Idle" Loop drinnen, der auf eine Eingabe wartet um aktiv zu werden. Was passiert denn da in dem Loop genau?

freimatz 9. Feb 2021 13:33

AW: Ursache für dauerhafte CPU-Auslastung finden
 
procmon?

Vielleicht bekommt die App Windows-Botschaften von ausserhalb.

CodeX 9. Feb 2021 15:15

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von freimatz (Beitrag 1482596)
procmon?
Vielleicht bekommt die App Windows-Botschaften von ausserhalb.

Habe jetzt eine Weile mit dem Process Monitor draufgeschaut. Die Anwendung macht im minimierten Zustand rein gar nichts. Zumindest nichts, was sich dort anzeigen ließe.

Und ich habe natürlich keinen Idle-Loop, der auf eine Eingabe wartet, sonst wüsste ich ja, wo das Problem zu suchen ist. Falls irgendsowas in einer Delphi-Unit drin ist, wäre ja genau das herauszufinden.

TiGü 10. Feb 2021 08:30

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Glaskugel sagt: Du hast einen externen Thread, der mit Sleep(...) in Dauerschleife läuft und irgendwas pollt/pollen soll.

Delphi.Narium 10. Feb 2021 09:48

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Meine Glaskugel tippt bei sowas immer zuerst auf 'nen Timer, der was macht, von dem keiner ahnt was er macht und keiner ahnt, dass er überhaupt existiert und von dem keiner weiß, ob sein "Arbeitsergebnis" überhaupt irgendeinen Sinn und Zweck hat oder irgendwen interessiert, ... :-(

CodeX 10. Feb 2021 09:55

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Bitte keine Glaskugeln ... im Projekt selbst wird soweit ich das sehen kann, kein Quatsch gemacht. Vielleicht in irgendeiner der verwendeten Komponenten.

Ich brauche ein gezielte Möglichkeit, die Ursache herauszufinden.
Das allererste Stichwort hier "AQTime" scheint mir immer noch eine gute Möglichkeit zu sein und es müsste kostenfrei verfügbar sein, aber ich weiß einfach nicht, wo ich das herbekommen soll. Im GetIt ist es (zumindest für Version 10.3) nicht und einen externen Download habe ich nicht gefunden. Wenn ja jemand was dazu hat oder etwas ähnliches wie AQTime. Oder irgendeine Debugger-Option, die einem anzeigt, wo gerade was gemacht wird bzw. eine Art Dauerlog der letzten Aufrufe.

Delphi.Narium 10. Feb 2021 10:22

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Naja, das Ergebnis meiner Glaskugel ist halt immer:

Es werden alle zum Projekt gehörenden Quelltexte nach TTimer durchsucht. Gibt's irgendwo 'ne Verwendung von TTimer, so wird an den entsprechenden Stelle geschaut, ob die Timer aktiv sind und was sie machen, ob sie erforderlich sind, ...

Bei Threads kann man bestimmt eine analoge Suche durchführen und so dort eine Ursachenermittlung machen ...

Deine Eingangsfrage war halt
Zitat:

Zitat von CodeX
Ich frage mich nun, wie ich die Ursache herausfinden kann.

...

Unsere "Glaskugeln" weisen auf übliche und üble Möglichkeiten für dauerhafte CPU-Auslastung hin und sollten mit Bordmitteln der IDE zu ermitteln sein, als Verursacher erkannt oder ausgeschlossen werden können, ...

Die Glaskugel kannst Du in diesem Zusammenhang als Synonym für "Langjährige Erfahrung in der Problemursachenforschung im Zusammenhang mit der Programmierung unter Zuhilfenahme einer entsprechenden und leistungsfähigen Entwicklungsumgebung" betrachten. Glaskugel klingt da irgendwie netter ;-)

TiGü 10. Feb 2021 11:09

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von CodeX (Beitrag 1482654)
Ich brauche ein gezielte Möglichkeit, die Ursache herauszufinden.
Das allererste Stichwort hier "AQTime" scheint mir immer noch eine gute Möglichkeit zu sein und es müsste kostenfrei verfügbar sein, aber ich weiß einfach nicht, wo ich das herbekommen soll.

Nanu, Internet kaputt?

Tut mir leid, wenn das etwas schnippisch rüber kommt, aber wenn ich AQTime in Google eintippe, fällt als erster Suchtreffer das hier raus:
https://smartbear.com/product/aqtime-pro/overview/
oder mit Trial noch als Suchbegriff dazu:
https://support.smartbear.com/more-i...me/trial-info/

Da gibt es allein auf der ersten Website vier Buttons ("Start My Free Trial", "Try AQTime Pro", "Try AQTime Pro Free", "Start a Free Trial") die alle nach Eingabe deiner Daten dir die Möglichkeit bieten, eine zeitlich begrenzte, aber vollfunktionsfähige Trial-Version runterzuladen (7 Tage).

Da gibt es neben einigen älteren, aber noch immer gültigen, Tutorial-Videos:
https://www.youtube.com/playlist?lis...F45D306F75252E
auch noch die die Dokumentation:
https://support.smartbear.com/aqtime...ampaign=supnav

Vielleicht arbeitest du ein paar der Dokumentationsseiten durch, verschaffst dir einen Überblick und startest dann morgen mit der Trial.

CodeX 10. Feb 2021 11:19

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Die Herstellerseite und dessen verschiedene Produktvarianten habe ich natürlich als erstes gesehen. Aber ich habe beim Weitersuchen auch gesehen, dass eine spezielle Version kostenlos bei der Delphi-Lizenz dabei ist. Wäre es nicht sinnvoller, die kostenfreie dauerhafte Version zu intallieren als eine 7-Tage-Trial? Da ich diese aus unbekannten Gründen nirgends finden kann, hatte ich die Hoffnung, dass hier jemand weiß, wo diese zu finden ist. Wie gesagt finde ich diese nicht im GetIt und bei den Embarcadero Downloads ist diese nur bis Version XE8 vorhanden. Irgendetwas scheine ich zu übersehen, daher die Frage. Wenn auch hier keiner weiter weiß, kann ich die Trial immer noch für diesen speziellen Fall versuchen (und nach einer Woche nie wieder verwenden können...).

TiGü 10. Feb 2021 11:29

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von CodeX (Beitrag 1482667)
Aber ich habe beim Weitersuchen auch gesehen, dass eine spezielle Version kostenlos bei der Delphi-Lizenz dabei ist. Wäre es nicht sinnvoller, die kostenfreie dauerhafte Version zu intallieren als eine 7-Tage-Trial? Da ich diese aus unbekannten Gründen nirgends finden kann, hatte ich die Hoffnung, dass hier jemand weiß, wo diese zu finden ist.

Nein, die taugte nichts und brachte auch einige Instabilitäten in die IDE.
Siehe:
https://www.delphipraxis.net/206406-...textmenue.html
https://www.delphipraxis.net/195999-...en-report.html

Probiere die Trial. Das Programm ist sein Geld auch wert.
Spart unnötige Optimierungsversuche ein, wenn man erstmal ermittelt, was die wirklichen Zeit- und Performancefresser sind.

CodeX 10. Feb 2021 12:07

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von TiGü (Beitrag 1482668)
Zitat:

Zitat von CodeX (Beitrag 1482667)
Aber ich habe beim Weitersuchen auch gesehen, dass eine spezielle Version kostenlos bei der Delphi-Lizenz dabei ist. Wäre es nicht sinnvoller, die kostenfreie dauerhafte Version zu intallieren als eine 7-Tage-Trial? Da ich diese aus unbekannten Gründen nirgends finden kann, hatte ich die Hoffnung, dass hier jemand weiß, wo diese zu finden ist.

Nein, die taugte nichts und brachte auch einige Instabilitäten in die IDE.
Siehe:
https://www.delphipraxis.net/206406-...textmenue.html
https://www.delphipraxis.net/195999-...en-report.html

Probiere die Trial. Das Programm ist sein Geld auch wert.
Spart unnötige Optimierungsversuche ein, wenn man erstmal ermittelt, was die wirklichen Zeit- und Performancefresser sind.

Danke für den Hinweis. Aber verstehe ich das richtig, dass die Standard Version (die bei Delphi irgendwo dabei ist), zu Problemen in der IDE führt, aber die kostenpflichtige Pro Version nicht? Klingt irgendwie seltsam...
Oder gar nicht in die IDE integrieren, sondern (was wohl auch geht) von extern das kompilierte Programm analysieren? Aber da gehen doch ganz viele Möglichkeiten verloren, die direkten Code-Stellen ausfindig zu machen, oder verstehe ich das falsch?
Auf der Produktseite steht "AQTime Pro integrates into Embarcadero RAD Studio". Ist das dann optional und sollte bei der Installation deaktiviert werden?
Sorry für die ganzen Nachfragen, aber scheinbar kann man dieses Tool ja nicht gefahrlos verwenden...

Uwe Raabe 10. Feb 2021 12:25

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Ist das Projekt zufällig ein MDI-Projekt und verwendet Actions?

TiGü 10. Feb 2021 12:53

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von CodeX (Beitrag 1482673)
Danke für den Hinweis. Aber verstehe ich das richtig, dass die Standard Version (die bei Delphi irgendwo dabei ist), zu Problemen in der IDE führt, aber die kostenpflichtige Pro Version nicht? Klingt irgendwie seltsam...
Oder gar nicht in die IDE integrieren, sondern (was wohl auch geht) von extern das kompilierte Programm analysieren? Aber da gehen doch ganz viele Möglichkeiten verloren, die direkten Code-Stellen ausfindig zu machen, oder verstehe ich das falsch?
Auf der Produktseite steht "AQTime Pro integrates into Embarcadero RAD Studio". Ist das dann optional und sollte bei der Installation deaktiviert werden?
Sorry für die ganzen Nachfragen, aber scheinbar kann man dieses Tool ja nicht gefahrlos verwenden...

Standard Version -> intergiert sich in IDE -> schlecht!
Trial/Pro Version -> kann, muss sich nicht integrieren -> gut!
von extern kompilierte Programm analysieren -> Ja!
die direkten Code-Stellen ausfindig zu machen -> geht mit der Pro Version. Man sagt über die Programmoptionen, wo die Quelltext-Dateien liegen und dann gibt's die zeilenweise Analyse.
Ist das dann optional und sollte bei der Installation deaktiviert werden? -> Ja!

CodeX 10. Feb 2021 14:45

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1482674)
Ist das Projekt zufällig ein MDI-Projekt und verwendet Actions?

Nein, "leider" nicht.

Zitat:

Zitat von TiGü (Beitrag 1482677)
Standard Version -> intergiert sich in IDE -> schlecht!
Trial/Pro Version -> kann, muss sich nicht integrieren -> gut!
von extern kompilierte Programm analysieren -> Ja!
die direkten Code-Stellen ausfindig zu machen -> geht mit der Pro Version. Man sagt über die Programmoptionen, wo die Quelltext-Dateien liegen und dann gibt's die zeilenweise Analyse.
Ist das dann optional und sollte bei der Installation deaktiviert werden? -> Ja!

Danke, dann werde ich das mal so machen und mich vorher erstmal zu AQTime einlesen. Hoffentlich komme ich damit auf den Grund.

Falls jemand noch einen anderen Ansatz weiß, was man z.B. direkt mit der Delphi IDE versuchen könnte, gerne her damit!
Oder wenn jemand noch eine Idee hat, was es mit der Stack-Info "TMethodImplementationIntercept" im Process Explorer auf sich haben könnte, auch gerne mitteilen.
Danke!

TiGü 10. Feb 2021 15:06

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von CodeX (Beitrag 1482685)
Zitat:

Zitat von Uwe Raabe (Beitrag 1482674)
Ist das Projekt zufällig ein MDI-Projekt und verwendet Actions?

Nein, "leider" nicht.

Ich nehme an, das Nein bezog sich auf MDI.
Bitte trotzdem mal alle TAction-Instanzen checken, ob da nicht doch irgendwo ein OnUpdate angemeldet ist, was dein Problem verursacht.
Ein Debuggen von TApplication.Idle und all der Aufrufe darin ist vielleicht auch noch ganz hilfreich, wenn du Timer und Threads ausschließen kannst.

Zitat:

Zitat von CodeX (Beitrag 1482685)
Oder wenn jemand noch eine Idee hat, was es mit der Stack-Info "TMethodImplementationIntercept" im Process Explorer auf sich haben könnte, auch gerne mitteilen.

Der Process Explorer schnappt sich einfach die erstbeste exportierte Funktion des Binary für den Mainthread, dass hat mit deinem Problem eher wenig zu tun.
Nimm mal ne neue und leere Applikation und öffne die im Dependency Walker oder Dependencies (https://github.com/lucasg/Dependencies).
Du wirst sehen, auch hier wird TMethodImplementationIntercept exportiert und der Mainthread wird in Process Explorer damit benannt.

TiGü 10. Feb 2021 15:11

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Ganz stumpf ist noch die Möglichkeit, das Programm auszuführen und mehrmals im Debugger anzuhalten (Pause).
Je nach Zufall landest du dann an der gesuchten "rechenintensiven" Codestelle.

Ein normaler Call Stack vom Mainthread sieht zumeist so aus:
Code:
:74e510cc win32u.NtUserWaitMessage + 0xc
:005c5e72 TApplication.Idle + $14E
Vcl.Forms.TApplication.HandleMessage
Vcl.Forms.TApplication.Run
Project2.Project2
:7607fa29 KERNEL32.BaseThreadInitThunk + 0x19
:76fd75f4 ntdll.RtlGetAppContainerNamedObjectPath + 0xe4
:76fd75c4 ntdll.RtlGetAppContainerNamedObjectPath + 0xb4
Das sollte bei dir dann abweichen, wenn du erfolgreich bist.

CodeX 10. Feb 2021 15:28

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Keine Verwendung von MDI oder TAction.

Ich habe alle Timer, die im gesamten Projekt vorkommen (Fremdkomponenten ausgenommen), in die Watch List hinzugefügt und das Programm im Debugger im Leerlauf angehalten: Alle Timer sind entweder Enabled:=False oder Inaccessible value, da in nicht initialisierten Forms oder Objekten.

Threads werden theoretisch verwendet, aber nicht automatisch nach dem Programmstart, sondern nur bei bestimmten Aktionen. Breakpoints bei deren Erstellung springen entsprechend auch nicht an. Der Process Explorer bestätigt das meiner Meinung ja auch, da dort die Auslastung im HauptThread liegt.

Wenn ich im Debugger auf Pause drücke, lande ich in der CPU Ansicht immer hier:
Code:
ntdll.RtlUserThreadStart:
775E3BE0 833DBC69697700   cmp dword ptr [$776969bc],$00
Darüber und darunter ist halt viel Assembler, aber keine Funktionsnamen o.ä. die mir irgendetwas sagen würden.
Lässt sich aus dieser Zeile schon etwas ableiten, was mir entgeht?

> Debuggen von TApplication.Idle
Was meinst Du damit genau? Im OnIdle Event von TApplication irgendwas einfügen, darauf einen Breakpoint setzen und schauen, was davor passiert ist? Oder wie?

TiGü 10. Feb 2021 16:34

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Für beide Fragen habe ich mal zwei kleine TeamViewer-Meetings aufgezeichnet, vielleicht wird's dann eher klar was ich von dir möchte.
https://drive.google.com/drive/folde...D6wFeYfGq1iese

How_to_Debug.tvs:
Der erste Thread in der Threadübersicht ist immer der Mainthread in der IDE.

How_to_Debug_2.tvs:
Debuggen der TApplication.Idle.
Voraussetzung: Project Options -> Delphi-Compiler -> Compiling -> Use debug .dcus muss auf True stehen.
Wenn deine IDE auf deutsch steht dann entsprechend die deutschen Begriffe.

CodeX 10. Feb 2021 17:28

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Oh, vielen Dank! :o

Das zweite Video hatte ich also im Prinzip zuvor richtig verstanden und auch geschaut, was danach passiert. (dazu gleich mehr)

Das erste Video hat mir aber schon mal ein bisschen weitergeholfen.
Der Haupt-Thread (TID auch mit Process Explorer abgeglichen), der die Auslastung verursacht landet beim Anhalten immer hier:
Code:
win32u.NtUserWaitMessage:
762E10C0 B80C100100       mov eax,$0001100c
762E10C5 BA10632E76       mov edx,$762e6310
762E10CA FFD2             call edx
762E10CC C3               ret              <------
762E10CD 8D4900           lea ecx,[ecx+$00]
Der zugehörige Stack Trace ist das hier:
Code:
:762e10cc win32u.NtUserWaitMessage + 0xc
:0070ec0b TApplication.Idle + $153
Vcl.Forms.TApplication.HandleMessage
Vcl.Forms.TApplication.Run
In diesem Teil von "TApplication.Run" lande ich auch, wenn ich von OnIdle weitergehe:
Delphi-Quellcode:
procedure TApplication.Run;
[...]
  repeat
    try
      HandleMessage;
    except
      HandleException(Self);
    end;
  until Terminated;
[...]
Dass die Anwendung auf Messages hört, überrascht mich jetzt eher nicht. Also ganz normales Verhalten? Oder sollte das so doch nicht sein?
Habe das mehrfach mit dem gleichen Ergebnis durchgespielt. Bringt es was, das ganz oft weiter zu wiederholen, in der Hoffnung, ein Mal wo anders zu landen beim Anhalten?

Uwe Raabe 10. Feb 2021 17:57

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Das WaitMessage wird am Ende von Idle aufgerufen. Es ist also durchaus normal wenn ein Programm dort steht.

Ich würde mal das Idle selbst analysieren. Dort können z.B. im FOnIdle oder DoActionIdle ein paar CPU-lastige Arbeiten stattfinden.

Übrigens ist die Angabe 0,1% - 0,2% CPU-Auslastung in Relation zu der Anzahl der verfügbaren logischen Prozessoren zu sehen. Bei einem Zweikern-System ist 1% wenig, bei einem 64-Kern System ist damit quasi ein Kern ausgelastet.

TiGü 10. Feb 2021 18:23

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Naja, gesamt gesehen hast du ja eine Auslastung von 2-3 Prozent auf einen Kern, du hattest es vorne irgendwo erwähnt.
Du müsstest also bei 100 zufälligen Pausieren in zwei bis drei Fällen zur betreffenden Codestelle kommen.
Wie ich oben sagte...ist halt ne sehr stumpfe Methode und mit AQTime wirste schneller zum Ziel kommen.

Deine Applikation sendet oder empfängt TCP oder UDP Kommunikation?

himitsu 10. Feb 2021 18:38

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Wenn dauern Messages reinkommen (z.B. weil irgendwer massiv mit Broadcasts um sich wirft), dann könnte man das mal mitzählen/loggen.
TApplicationEvents.OnMessage

* aber OnMessage bekommt nur PostMessage mit, exclusive WM_WIMER
* und wenn irgendwo Messages außerhalb der VCL verarbeitet werden, dann geht das auch unter (z.B. haben MessageBox und Open-/SaveDialoge innen eine eigene Message-Loop, so lange der Dialog angezeigt wird)
* und für SendMessage bräuchte man einen anderen Hook

Monday 10. Feb 2021 19:40

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Könnte ein Profiler hier weiterhelfen?!

CodeX 10. Feb 2021 20:04

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Ich habe jetzt mal analysiert, wo/wie die Messages in der Anwendung verarbeitet werden. Es existiert eine zentrale Prozedur, wo alle Messages erst durchgehen:
Delphi-Quellcode:
Application.HookMainWindow(HookAppProc);

[...]

function TKlasse.HookAppProc(var Msg: TMessage): Boolean;
begin
  OutputDebugString(PChar('### MSG App ' + Msg.WParam.ToString +'/'+ Msg.LParam.ToString)); //Das habe ich jetzt hinzugefügt
  Result := False; //Should always be False unless we don't want the default message handling
  case Msg.Msg of
    WM_SIZE: ...
    WM_CLOSE: ...
    WM_SYSCOMMAND: ...
    ...
  end;
end;
Ich glaube, das an sich sollte nicht das Problem sein, aber die neu hinzugefügte Debug-Zeile haut quasi ununterbrochen "0/0" Meldungen raus und tatsächlich gehen da offenbar ununterbrochen "leere" Messages durch (also in Msg ist alles 0). In der genannten Funktion passiert damit nichts, da es nach der case Abfrage gleich wieder rausspringt, aber vielleicht liegt das Problem dennoch hier?
Ist es normal, dass ununterbrochen leere Messages reinkommen? Wenn nicht, habe ich eine Chance, die Quelle der Messages herauszufinden (oder zumindest ob von außerhalb oder von einer anderen Stelle im Projekt)? Vielleicht kommt ja dann genau hier AQTime ins Spiel?

jfheins 10. Feb 2021 20:13

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von Monday (Beitrag 1482722)
Könnte ein Profiler hier weiterhelfen?!

Ja, klar. AQTime wurde ja bereits genannt ;-)

Zitat:

Zitat von CodeX (Beitrag 1482725)
die neu hinzugefügte Debug-Zeile haut quasi ununterbrochen "0/0" Meldungen raus und tatsächlich gehen da offenbar ununterbrochen "leere" Messages durch (also in Msg ist alles 0).

Auch die msg ID? Also "Msg.Msg" ? Die ist das eigentlich Interessante. Ich würde jetzt tippen, ein Dutzend Messages pro Sekunde ist noch normal, hast du vll. genauere Zahlen wie viele da pro Sekunde laufen?
Evtl. einfach mal mit Zeitstempel und Msg ID loggen.

CodeX 10. Feb 2021 20:22

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von jfheins (Beitrag 1482726)
Auch die msg ID? Also "Msg.Msg" ?

Sorry, ja, auch Msg.Msg.

So sieht der Log von
Delphi-Quellcode:
OutputDebugString(PChar('### MSG App ' + GetTickCount.ToString + ' ' + Msg.Msg.ToString));
aus:
Code:
Debug Output: ### MSG App 1484513750 0 Process App.exe (16484)
Debug Output: ### MSG App 1484513781 0 Process App.exe (16484)
Debug Output: ### MSG App 1484513812 0 Process App.exe (16484)
Debug Output: ### MSG App 1484513843 0 Process App.exe (16484)
Debug Output: ### MSG App 1484513875 0 Process App.exe (16484)
Debug Output: ### MSG App 1484513906 0 Process App.exe (16484)
Debug Output: ### MSG App 1484513937 0 Process App.exe (16484)
Debug Output: ### MSG App 1484513968 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514015 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514046 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514078 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514109 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514140 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514171 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514218 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514250 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514281 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514312 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514343 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514375 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514406 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514437 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514468 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514515 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514531 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514562 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514593 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514609 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514640 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514671 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514718 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514750 0 Process App.exe (16484)
Debug Output: ### MSG App 1484514781 0 Process App.exe (16484)
Ist das normal?

himitsu 10. Feb 2021 20:30

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Findest irgendwo im Programmcode und Fremdkomponenten ein WM_NULL?


FMX/VCL (TPlatformWin/TApplication.WakeMainThread), Indy, OleControl's und paar Andere lösen ein WM_NULL aus, damit der Hauptthread z.B. die TThread.Synchronize verarbeitet.

jfheins 10. Feb 2021 20:31

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Normal ist relativ :stupid:

WM_Null Messages kommen wohl normalerweise nicht so oft vor. Aber es gibt bestimmte Software, die das verschickt bspw. um zu prüfen ob die Vordergrundfenster noch reagieren. Guck mal hier: https://devblogs.microsoft.com/oldne...02-00/?p=96266

Liegt dann vll. doch gar nicht an deinem Programm.

CodeX 10. Feb 2021 22:11

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von himitsu (Beitrag 1482728)
Findest irgendwo im Programmcode und Fremdkomponenten ein WM_NULL?
FMX/VCL (TPlatformWin/TApplication.WakeMainThread), Indy, OleControl's und paar Andere lösen ein WM_NULL aus, damit der Hauptthread z.B. die TThread.Synchronize verarbeitet.

In meinem Projekt habe ich das nicht gefunden. Bei den Komponenten habe ich WM_NULL bei Indy nur in Kommentaren gefunden (wird ohnehin nicht automatisch nach dem Programmstart verwendet). Aber theoretisch könnte es ja auch als "0" und nicht als "WM_NULL" im Quelltext irgendwo enthalten sein.

Zitat:

Zitat von jfheins (Beitrag 1482729)
Normal ist relativ :stupid:
WM_Null Messages kommen wohl normalerweise nicht so oft vor.[/url]

Dann anders formuliert: Können 33 Null-Messages pro Sekunde Grund für eine Auslastung von 2-3% auf einem logischen Prozessorkern sein?
Wenn ja, müsste das dann nicht jede Anwendung gleichermaßen betreffen? Messages werden nach meinem Verständnis normalerweise ja in jeder Anwendung empfangen und verarbeitet - selbst wenn nicht vom Entwickler explizit, dann dennoch vom Programmgrundgerüst für ganz normale Aktionen wie minimieren, etc.
Oder kann die Verwendung von HookMainWindow dazu führen?

Zitat:

Zitat von jfheins (Beitrag 1482729)
Liegt dann vll. doch gar nicht an deinem Programm.

Ehrlich gesagt, finde ich das gar nicht so wichtig. Wenn die Ursache in meinem Programm liegt, würde ich natürlich gerne die Ursache beheben. Wenn die Ursache aber extern liegt, dann würde ich zumindest gerne die Auswirkungen beheben. Sollte es an den Messages liegen: Wenn jetzt plötzlich 330 statt 33 davon pro Sekunde eingehen, dann führt das zu einer Auslastung von 20-30%? Und bei 1000 Messages dann zum kompletten Lockup? Das kann es ja nicht sein.

Und wie gesagt: Ich sehe im Process Explorer ja, dass keine andere Anwendung dieses Verhalten zeigt. Die anderen Prozesse sind entweder konstant 0, ab und an kurz "< 0.01" oder es handelt sich tatsächlich um Prozesse, die etwas tun (Browser, AntiVirus, etc.).

Ich werde mich jetzt ein bisschen in AQTime einarbeiten und es morgen damit versuchen. Dennoch finde ich diese Analyse vorab sehr sinnvoll, um zu verstehen, was als Ursache überhaupt in Frage kommt. Hätte ja sein können, dass sich das auch so herausfinden und beheben lässt.

himitsu 11. Feb 2021 10:06

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Aber theoretisch könnte es ja auch als "0" ...
Neeee neee neeee, alle Programmierer sind ja intelligent und verwenden vorhandene Konstanten, anstatt irgendwelcher wilder Magicvalues. :roll:

Sinspin 14. Feb 2021 14:45

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Dein Programm ist in SysTray minimiert wenn das Auftritt. Nur dann hast du CPU load? Oder auch wenn das Programm sichtbar ist?
...Ich kann mich erinnern das ich früher mal eine SysTray Komponente in Verwendung hatte die CPU verbraten hat wenn man die Animationsfunktion für das angezeigt Icon aktiviert hat.
Irgendwann bin ich dann auf eine andere umgestiegen oder das Verhalten war nach einer Aktualisierung weg. Ich kann mich aber nicht mehr erinnern.

TiGü 23. Feb 2021 08:24

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Wie ist das denn ausgegangen?

CodeX 9. Mär 2021 18:48

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Zitat:

Zitat von TiGü (Beitrag 1483551)
Wie ist das denn ausgegangen?

Tut mir leid für die sehr späte Rückmeldung...
AQTime hatte mich nur bedingt weitergebracht. Da es leider nur Laufzeiten und nicht irgendeine Form von Auslastung misst (zumindest habe ich nichts dergleichen gefunden), hatte ich darin nur als Bestätigung erkennen können, welche Threads dauerhaft laufen. Das hatte ich im Grunde auch vorher schon eingrenzen können, aber nun hatte ich zumindest eine Art Bestätigung. Die dauerhaften Threads gehören zu Dritt-Komponenten und sind fast alle auch harmlos gewesen. Bspw. hat VirtualTreeView einen dauerhaften WorkerThread, der aber wirklich nur etwas tut, wenn es was zu tun gibt. Die Ursache lag nach einigem Hin und Her in einer Komponente, die im Thread einen Timer startet und dieser zeichnet die Komponente neu, um diverse Animationen darin abbilden zu können. Testweises Deaktivieren des darin enthaltenen Timers entfernte auch die beobachtete CPU-Auslastung vollständig. Da die Ursache nicht im Hauptprogramm liegt, brauche ich da aber erstmal nichts dran weiterzumachen, sondern habe das entsprechend weitergereicht.
Ich bin hauptsächlich froh darüber, dass es nicht an den Messages o.ä. liegt.
Vielen Dank an alle für die Unterstützung!

TiGü 10. Mär 2021 07:48

AW: Ursache für dauerhafte CPU-Auslastung finden
 
Danke für die Rückmeldung.
Zitat:

Zitat von CodeX
Die Ursache lag nach einigem Hin und Her in einer Komponente, die im Thread einen Timer startet und dieser zeichnet die Komponente neu, um diverse Animationen darin abbilden zu können.

Man beachte, wie zutreffend im Nachhinein das Glaskugel-Raten aus Beitrag #10 und #11 waren. :lol:

Um welche Dritt-Komponente handelt es sich denn?
Könnte hilfreich sein für spätere Generationen, die hier per Google drüber stolpern.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:16 Uhr.
Seite 1 von 2  1 2      

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