NEWS
Load average am Anschlag -> Neustart
-
@Michael-Schmitt klingt sinnvoll.
Aber ich weiss ja auch nicht was hier abgeht
Wollte gerade los ne nvme und eine icybox zu holen um den anderen pi mit wasauchimmer als OS zu füttern und sehen ob es auch dann die selben Probleme gibt.
Hab es auf morgen verschobenwieder die bisherigen logdateien löschen und dann
den service neu starten
sudo chmod +x /usr/local/sbin/memwatch.sh sudo systemctl restart memwatch.service systemctl status memwatch.serviceopenai ist wohl gerade überlastet. konnte die dateien über chatgpt nicht hochladen. musste zu codex cli lokal wechseln
-
hier die neue analyse. leider mit noch nicht ganz so eindeutigen hinweisen.
auch leben diese tasks zu kurz als das der 5 sekunden rythmus ausgereicht hätte. das Ereignis um 14:21 war auch nicht stark genug.
Analyse der memwatch-Logs vom 31.08.2026
Kurzfazit
Die Dateien belegen einen kurzlebigen Task-/Thread-Sturm am 31.08.2026 um
14:21:36. Innerhalb eines Messintervalls von fünf Sekunden stieg die Taskzahl
von 679 auf 891, also um 212. Gleichzeitig gingen rund 400 MB verfügbarer
Speicher verloren.Der Sturm war beim Schreiben des detaillierten Snapshots bereits teilweise
vorbei: Dort wurden nur noch 736 Tasks gezählt. Deshalb ist der eigentliche
Verursacher in der normalen Prozessliste nicht mehr vollständig enthalten.Der auffälligste zeitliche Zusammenhang ist der ioBroker-Adapter
system.adapter.dwd.0: Sein Prozessio.dwd.0(PID 229073, Parent PID 39859)
wurde um 14:21:33 gestartet, nur drei Sekunden vor dem Peak. Im Snapshot
belegte er bereits 180.544 kB RSS. Damit istdwd.0der derzeit stärkste
Verdächtige, aber anhand dieser Dateien noch nicht zweifelsfrei als Erzeuger
aller 212 zusätzlichen Tasks bewiesen.Ausgewertete Dateien
1788179405632-1424memory.log1788179326889-snapshot_20260831_140543.log1788179326893-snapshot_20260831_141701.log1788179326891-snapshot_20260831_142136.log
Erkannte Ereignisse
Zeitpunkt MemFree-Abfall MemAvailable-Abfall Taskänderung Tasks am Trigger Besonderheit 14:05:43 392 MB 301 MB +3 652 Speicherimpuls ohne Task-Sturm 14:17:01 285 MB 285 MB +18 678 Speicherimpuls, kleiner Taskanstieg 14:21:36 389 MB 400 MB +212 891 klarer Task-/Thread-Sturm Alle drei Ereignisse waren kurzlebig. Bereits bei den jeweils nächsten
Messungen hatte sich ein wesentlicher Teil des Speicherverbrauchs wieder
zurückgebildet. Das spricht eher für kurz gestartete Prozesse/Threads oder eine
kurze, speicherintensive Adapteraktivität als für ein stetiges Speicherleck.Detailanalyse des Ereignisses um 14:21:36
Zwischen den beiden Messpunkten änderten sich die wichtigsten Werte ungefähr
wie folgt:- Tasks: 679 -> 891 (+212)
- MemAvailable: 3.546 MB -> 3.146 MB (-400 MB)
- MemFree: 2.908 MB -> 2.519 MB (-389 MB)
AnonPages: etwa 3.428 MB -> 3.807 MB (ca. +379 MB)PageTables: etwa 340 MB -> 376 MB (ca. +36 MB)KernelStack: etwa 10,6 MB -> 13,9 MB (ca. +3,2 MB)
Die Kombination aus deutlich steigenden
AnonPages,PageTables,
KernelStackund Tasks passt technisch zu sehr vielen kurzfristig angelegten
Ausführungskontexten. Sie passt weniger zu einem reinen Dateicache- oder
Slab-Problem.Der Snapshot zeigt unmittelbar danach:
- 242 Prozesse und 736 Tasks; gegenüber den 891 Tasks am Trigger waren also
bereits 155 Tasks wieder verschwunden. io.dwd.0, PID 229073, PPID 39859, gestartet um 14:21:33.io.dwd.0hatte 12 noch sichtbare Threads und 180.544 kB RSS.- Der ioBroker-Controller PID 39859 war der Parent der Adapterprozesse.
- Kein noch sichtbarer Prozess hatte im Snapshot eine ungewöhnlich hohe
Threadzahl; die ioBroker-/Node-Prozesse lagen überwiegend bei 11 oder 12.
Das bedeutet: Die zusätzlichen Tasks waren entweder sehr kurzlebig oder der
Peak wurde in einer Phase erfasst, die vor dem erstenps-Snapshot schon
endete. Die verbleibenden 12 Threads vondwd.0erklären den Peak allein
nicht. Der Startzeitpunkt und sein hoher anfänglicher RSS machen den Adapter
aber zum besten konkreten Ansatzpunkt.Die anderen beiden Ereignisse
14:05:43
Der Speicherverlust von 301 MB bei
MemAvailabletrat bei nur drei zusätzlichen
Tasks auf. Die Prozessliste zeigt keinen Thread-Sturm und keinen einzelnen neu
gestarteten Großverbraucher. Der Effekt bildete sich schnell zurück.14:17:01
Der Speicherverlust von 285 MB trat zusammen mit 18 zusätzlichen Tasks auf.
Auch hier zeigt der Snapshot keinen Prozess mit auffälliger Threadzahl. Um
14:17:01 lief zusätzlich/etc/cron.hourly; das ist zeitlich korreliert, aber
die vorliegenden Daten belegen keine ursächliche Verbindung.Weitere relevante Beobachtungen
- Swap war bereits mit etwa 1,1 GiB von 2,0 GiB belegt. Während der fünf
vmstat-Sekunden fand beim Ereignis aber kein aktuelles Ein- oder Ausswappen
statt (si/sojeweils 0 nach der Summenzeile). - Die CPU-Last stieg kurz an und fiel innerhalb weniger Sekunden wieder ab.
- Die Slab-Auswertung war unauffällig; insbesondere erklärt der Slab-Verbrauch
nicht den kurzfristigen Verlust von etwa 400 MB. - Es gab während dieser drei Snapshots keinen neuen OOM-Kill. Die in
dmesg
enthaltenen OOM-Einträge stammen von 23:58:02 und 00:24:01 und damit aus
früheren Ereignissen. Damals wurden ioBroker-Controller-Prozesse beendet. - Die SSH-Anmeldung des Benutzers
puhum 14:13 erzeugte nur wenige Prozesse
und erklärt den Peak um 14:21 nicht.
Fehler und Lücken im aktuellen Messskript
1. Parent-Auswertung bricht ab
Im Journal steht bei jedem Snapshot:
/usr/local/sbin/memwatch.sh: line 264: PPID: readonly variablePPIDist in Bash eine reservierte, schreibgeschützte Variable. Dadurch bleibt
der AbschnittTOP PARENTS WITH PROCESS INFORMATIONleer. In der Schleife muss
die Variable beispielsweisePARENT_PIDheißen:while read -r COUNT PARENT_PID; do if [[ "$PARENT_PID" =~ ^[0-9]+$ ]] && [ "$PARENT_PID" -gt 0 ]; then INFO="$(ps -p "$PARENT_PID" -o pid=,ppid=,user=,nlwp=,rss=,vsz=,stat=,comm=,args= 2>/dev/null)" printf "%6s children | %s\n" "$COUNT" "$INFO" fi done2.
FULL THREAD LISTist leerIn allen drei Snapshots folgt direkt nach der Überschrift
FULL THREAD LIST
bereitsPROCESS TREE. Das verwendeteps -eLf -o ...liefert auf diesem
System offenbar keine Daten (der Fehler wird durch2>/dev/nullverborgen).
Vor dem nächsten Lauf sollte der Befehl direkt auf dem Raspberry Pi getestet
werden. Eine robustere Variante ist beispielsweise:ps -eL -o pid,ppid,lwp,nlwp,user,psr,stat,rss,vsz,comm,args3. Snapshot-Erfassung dauert etwa fünf Sekunden
Zwischen Triggerzeit und
snapshot writtenliegen jeweils vier bis fünf
Sekunden. Schon vor dem ersten detaillierten Taskwert war beim stärksten
Ereignis ein großer Teil des Sturms vorbei. Für solche Peaks sollte beim Trigger
zuerst eine sehr schnelle Rohkopie von/procbeziehungsweise mindestens eine
sofortige Threadliste in eine separate Datei geschrieben werden. Erst danach
sollten Sortierungen und mehrfacheps-Aufrufe folgen.4. Taskzahl im Trigger und Snapshot unterscheiden sich
Das ist kein Rechenfehler:
memory.logmisst 891 Tasks am Trigger, während der
nachfolgende Snapshot 736 anzeigt. Diese Differenz ist gerade ein wichtiger
Hinweis auf die kurze Lebensdauer der zusätzlichen Tasks.Bewertung der wahrscheinlichsten Ursache
- Sehr wahrscheinlich: ein kurzlebiger Prozess-/Thread-Sturm verursacht
den starken Peak um 14:21:36. - Wahrscheinlichster konkreter Auslöser: Start oder Startaktivität von
system.adapter.dwd.0, daio.dwd.0drei Sekunden vor dem Peak neu gestartet
wurde und unmittelbar 180 MB RSS belegte. - Noch nicht bewiesen: Ob
dwd.0selbst alle zusätzlichen Tasks erzeugte,
ob ein von ihm ausgelöster Node-/Systemvorgang beteiligt war oder ob ein
zeitgleicher, bereits verschwundener Prozess verantwortlich war. - Unwahrscheinlich als alleinige Ursache: Slab, Dateicache, SSH-Sitzung oder
ein dauerhaft wachsender einzelner ioBroker-Prozess.
Empfohlene nächste Schritte
- Die Variable
PPIDim Skript inPARENT_PIDumbenennen. - Den Befehl für
FULL THREAD LISTkorrigieren und seine Fehler vorübergehend
nicht nach/dev/nullumleiten. - ioBroker-Logs für
system.adapter.dwd.0im Zeitraum 14:21:25 bis 14:21:45
sichern und prüfen, warum der Adapter um 14:21:33 gestartet wurde. - In den ioBroker-Objekten/Logs die Restart-Zahl und den Exit-Grund von
dwd.0prüfen. - Für den nächsten Peak eine minimale Soforterfassung vor allen aufwendigen
Befehlen ergänzen, etwaps -eL ...und eine Liste aller numerischen
/proc/<PID>/task/<TID>-Einträge. - Optional
dwd.0kontrolliert deaktivieren und beobachten, ob die Peaks
ausbleiben. Das wäre ein aussagekräftiger A/B-Test, sollte aber nur erfolgen,
wenn der vorübergehende Ausfall der DWD-Daten akzeptabel ist.
Gesamtergebnis
Das verbesserte Monitoring hat die bisherige Vermutung grundsätzlich bestätigt:
Mindestens eines der Speicherereignisse ist mit einem massiven, sehr kurzen
Taskanstieg gekoppelt. Der Snapshot kam noch knapp zu spät, um sämtliche Tasks
ihrem Prozess zuzuordnen.dwd.0ist aufgrund seines Startzeitpunkts der klare
Hauptverdächtige. Für einen belastbaren Beweis müssen die beiden fehlerhaften
Snapshot-Abschnitte repariert und die erste Threadliste noch früher geschrieben
werden.leider mit noch nicht ganz so eindeutigen hinweisen.
Ich hätte jetzt was neues für dich
Die snapshots kommen im minutentakt

snapshot_20260831_153941.log snapshot_20260831_153921.log snapshot_20260831_153841.log snapshot_20260831_153541.log snapshot_20260831_153440.log snapshot_20260831_153339.log snapshot_20260831_153309.log snapshot_20260831_153240.log snapshot_20260831_153140.log snapshot_20260831_153040.log 1540memory.log
Ich sehe mir jetzt sofort deine Vorschläge an
-
So,
Neues Programm läuft!Dwd.0 hat wohl Probleme mit der gesicherten Verbindung.
Das hatte das log zugespammt.Ich glaube da wurde nur das logging deaktiviert.
Dwd ist scheduled, daher due Aussage "direkt nach dem start...."
-
Ich will nicht zu viel schicken!
Hier mit neuem Programm und hoher load

Hier ist grün die load!!
Bis zum AnschlagUnd logs noch und nöcher
snapshot_20260831_160141.log snapshot_20260831_160241.log snapshot_20260831_160346.log snapshot_20260831_160451.log snapshot_20260831_160542.log snapshot_20260831_155944.log
Ich würde erst wieder etwas senden, wenn deine KI mehr Informationen braucht oder der iob gekillt wurde
*DANKE!!K
-
Ich will nicht zu viel schicken!
Hier mit neuem Programm und hoher load

Hier ist grün die load!!
Bis zum AnschlagUnd logs noch und nöcher
snapshot_20260831_160141.log snapshot_20260831_160241.log snapshot_20260831_160346.log snapshot_20260831_160451.log snapshot_20260831_160542.log snapshot_20260831_155944.log
Ich würde erst wieder etwas senden, wenn deine KI mehr Informationen braucht oder der iob gekillt wurde
*DANKE!!K
da war jetzt nur das um 1605 mit dem neuen skript von den snapshots.
wir sammeln noch ein wenig.
gut, der höher load kommt nun auch ein wenig von dem skriptohne bisher die ki zu fragen ist mir aber an den letzten snapshots bspw beim
1788185456278-snapshot_20260831_153339.log
folgendes aufgefallen285056 39891 iobroker 7 0.6 49664 751040 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"system.host.ioBrokerpi5.freemem","path":"/mnt/usbplatte/data/history/","start":1788161558739,"end":1788183158739,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1056,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"alias.0.Host.freeMem17881832179450.39450520995403915","round":null,"logDebug":false} 285057 39891 iobroker 7 0.6 49568 554320 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"Messwerte.0.HardwareDaten.Master.Speicher.mem_free","path":"/mnt/usbplatte/data/history/","start":1788161558739,"end":1788183158739,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1056,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"Messwerte.0.HardwareDaten.Master.Speicher.mem_free17881832179480.4657008882857676","round":null,"logDebug":false} 285059 39891 iobroker 7 0.6 49584 750816 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"alias.0.Host.memAvailable","path":"/mnt/usbplatte/data/history/","start":1788161558739,"end":1788183158739,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1056,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"alias.0.Host.memAvailable17881832179540.45382242273599815","round":null,"logDebug":false} 285064 39891 iobroker 7 0.5 49104 617424 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"Messwerte.0.HardwareDaten.Master.Speicher.memBuffered","path":"/mnt/usbplatte/data/history/","start":1788161558739,"end":1788183158739,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"minmax","limit":300,"addId":false,"sessionId":1056,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"Messwerte.0.HardwareDaten.Master.Speicher.memBuffered17881832179590.4791995853762201","round":null,"logDebug":false} 285071 39891 iobroker 7 0.6 49680 685296 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"system.host.ioBrokerpi5.freemem","path":"/mnt/usbplatte/data/history/","start":1788161558741,"end":1788183158741,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1057,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"alias.0.Host.freeMem17881832179680.021342402309211916","round":null,"logDebug":false} 285077 39891 iobroker 7 0.6 49600 750816 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"alias.0.Host.memAvailable","path":"/mnt/usbplatte/data/history/","start":1788161558741,"end":1788183158741,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1057,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"alias.0.Host.memAvailable17881832179820.20277489329472664","round":null,"logDebug":false} 285093 39891 iobroker 7 0.5 49104 617424 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"Messwerte.0.HardwareDaten.Master.Speicher.memBuffered","path":"/mnt/usbplatte/data/history/","start":1788161558741,"end":1788183158741,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"minmax","limit":300,"addId":false,"sessionId":1057,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"Messwerte.0.HardwareDaten.Master.Speicher.memBuffered17881832179950.6046703034490128","round":null,"logDebug":false}davon gibt es noch mehr zeilen und wahrscheinlich sind das nicht alle, da das skript nur die ersten paar aufzeichnet.
jede zeile ist ein eigener task
den einzigen kandidaten hab ich hier gefunden
https://github.com/ioBroker/ioBroker.history/blob/6957d59c009494caf798bea9fb32fe57c8b17f53/src/lib/getHistory.ts#L142
da scheint wohl node solche operationen als eigenen task auszuführen.
Das ist die Stelle bei der der history adapter die tagesdatei zu einem Datenpunkt liest.aber wie weiter oben schon mal erwähnt und zu überprüfen:
zeichnest du insbesondere bei den speicherrelevanten datenpunkten JEDE Änderung auf?
ich weiß nicht in welchem zeittakt der iobroker intern die datenpunkte aktualisiert. die gehen dann ja auch in die history und wenn da alle paar millisekunden bzw 100 millisekunden eine änderung gibt, dann werden entsprechend viele dateien geöffnet.
gut der history adapter sammelt ein wenig die daten in einem cache, aber wenn der voll ist, muss er schreiben. -
Ich will nicht zu viel schicken!
Hier mit neuem Programm und hoher load

Hier ist grün die load!!
Bis zum AnschlagUnd logs noch und nöcher
snapshot_20260831_160141.log snapshot_20260831_160241.log snapshot_20260831_160346.log snapshot_20260831_160451.log snapshot_20260831_160542.log snapshot_20260831_155944.log
Ich würde erst wieder etwas senden, wenn deine KI mehr Informationen braucht oder der iob gekillt wurde
*DANKE!!K
-
da war jetzt nur das um 1605 mit dem neuen skript von den snapshots.
wir sammeln noch ein wenig.
gut, der höher load kommt nun auch ein wenig von dem skriptohne bisher die ki zu fragen ist mir aber an den letzten snapshots bspw beim
1788185456278-snapshot_20260831_153339.log
folgendes aufgefallen285056 39891 iobroker 7 0.6 49664 751040 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"system.host.ioBrokerpi5.freemem","path":"/mnt/usbplatte/data/history/","start":1788161558739,"end":1788183158739,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1056,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"alias.0.Host.freeMem17881832179450.39450520995403915","round":null,"logDebug":false} 285057 39891 iobroker 7 0.6 49568 554320 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"Messwerte.0.HardwareDaten.Master.Speicher.mem_free","path":"/mnt/usbplatte/data/history/","start":1788161558739,"end":1788183158739,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1056,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"Messwerte.0.HardwareDaten.Master.Speicher.mem_free17881832179480.4657008882857676","round":null,"logDebug":false} 285059 39891 iobroker 7 0.6 49584 750816 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"alias.0.Host.memAvailable","path":"/mnt/usbplatte/data/history/","start":1788161558739,"end":1788183158739,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1056,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"alias.0.Host.memAvailable17881832179540.45382242273599815","round":null,"logDebug":false} 285064 39891 iobroker 7 0.5 49104 617424 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"Messwerte.0.HardwareDaten.Master.Speicher.memBuffered","path":"/mnt/usbplatte/data/history/","start":1788161558739,"end":1788183158739,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"minmax","limit":300,"addId":false,"sessionId":1056,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"Messwerte.0.HardwareDaten.Master.Speicher.memBuffered17881832179590.4791995853762201","round":null,"logDebug":false} 285071 39891 iobroker 7 0.6 49680 685296 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"system.host.ioBrokerpi5.freemem","path":"/mnt/usbplatte/data/history/","start":1788161558741,"end":1788183158741,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1057,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"alias.0.Host.freeMem17881832179680.021342402309211916","round":null,"logDebug":false} 285077 39891 iobroker 7 0.6 49600 750816 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"alias.0.Host.memAvailable","path":"/mnt/usbplatte/data/history/","start":1788161558741,"end":1788183158741,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1057,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"alias.0.Host.memAvailable17881832179820.20277489329472664","round":null,"logDebug":false} 285093 39891 iobroker 7 0.5 49104 617424 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"Messwerte.0.HardwareDaten.Master.Speicher.memBuffered","path":"/mnt/usbplatte/data/history/","start":1788161558741,"end":1788183158741,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"minmax","limit":300,"addId":false,"sessionId":1057,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"Messwerte.0.HardwareDaten.Master.Speicher.memBuffered17881832179950.6046703034490128","round":null,"logDebug":false}davon gibt es noch mehr zeilen und wahrscheinlich sind das nicht alle, da das skript nur die ersten paar aufzeichnet.
jede zeile ist ein eigener task
den einzigen kandidaten hab ich hier gefunden
https://github.com/ioBroker/ioBroker.history/blob/6957d59c009494caf798bea9fb32fe57c8b17f53/src/lib/getHistory.ts#L142
da scheint wohl node solche operationen als eigenen task auszuführen.
Das ist die Stelle bei der der history adapter die tagesdatei zu einem Datenpunkt liest.aber wie weiter oben schon mal erwähnt und zu überprüfen:
zeichnest du insbesondere bei den speicherrelevanten datenpunkten JEDE Änderung auf?
ich weiß nicht in welchem zeittakt der iobroker intern die datenpunkte aktualisiert. die gehen dann ja auch in die history und wenn da alle paar millisekunden bzw 100 millisekunden eine änderung gibt, dann werden entsprechend viele dateien geöffnet.
gut der history adapter sammelt ein wenig die daten in einem cache, aber wenn der voll ist, muss er schreiben.da scheint wohl node solche operationen als eigenen task auszuführen.
Aaah, das passt!
Unter top tauchte ab und zu ei prozess "node" auf und verschwand sofort wieder
die gehen dann ja auch in die history und wenn da alle paar millisekunden bzw 100 millisekunden
Nein, die sind nur höchstens alkec6 Sekunden.
Da müsste ich die system.host und system.adapter DP sicherheitshalber mal mit einer Blockzeit belegen!
Danke für den Tippda war jetzt nur das um 1605 mit dem neuen skript von den snapshots.
Dann hab ich vielleicht die falschen hochgeladen.
Muss ich checken und tausche ggf. Aussende insbesondere die snapshot, die größer wie 200k sind.
wenn ein oom kill dabei ist umso besserOk!
Damit kann ich was anfangen -
da war jetzt nur das um 1605 mit dem neuen skript von den snapshots.
wir sammeln noch ein wenig.
gut, der höher load kommt nun auch ein wenig von dem skriptohne bisher die ki zu fragen ist mir aber an den letzten snapshots bspw beim
1788185456278-snapshot_20260831_153339.log
folgendes aufgefallen285056 39891 iobroker 7 0.6 49664 751040 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"system.host.ioBrokerpi5.freemem","path":"/mnt/usbplatte/data/history/","start":1788161558739,"end":1788183158739,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1056,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"alias.0.Host.freeMem17881832179450.39450520995403915","round":null,"logDebug":false} 285057 39891 iobroker 7 0.6 49568 554320 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"Messwerte.0.HardwareDaten.Master.Speicher.mem_free","path":"/mnt/usbplatte/data/history/","start":1788161558739,"end":1788183158739,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1056,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"Messwerte.0.HardwareDaten.Master.Speicher.mem_free17881832179480.4657008882857676","round":null,"logDebug":false} 285059 39891 iobroker 7 0.6 49584 750816 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"alias.0.Host.memAvailable","path":"/mnt/usbplatte/data/history/","start":1788161558739,"end":1788183158739,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1056,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"alias.0.Host.memAvailable17881832179540.45382242273599815","round":null,"logDebug":false} 285064 39891 iobroker 7 0.5 49104 617424 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"Messwerte.0.HardwareDaten.Master.Speicher.memBuffered","path":"/mnt/usbplatte/data/history/","start":1788161558739,"end":1788183158739,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"minmax","limit":300,"addId":false,"sessionId":1056,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"Messwerte.0.HardwareDaten.Master.Speicher.memBuffered17881832179590.4791995853762201","round":null,"logDebug":false} 285071 39891 iobroker 7 0.6 49680 685296 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"system.host.ioBrokerpi5.freemem","path":"/mnt/usbplatte/data/history/","start":1788161558741,"end":1788183158741,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1057,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"alias.0.Host.freeMem17881832179680.021342402309211916","round":null,"logDebug":false} 285077 39891 iobroker 7 0.6 49600 750816 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"alias.0.Host.memAvailable","path":"/mnt/usbplatte/data/history/","start":1788161558741,"end":1788183158741,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"min","limit":300,"addId":false,"sessionId":1057,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"alias.0.Host.memAvailable17881832179820.20277489329472664","round":null,"logDebug":false} 285093 39891 iobroker 7 0.5 49104 617424 Sl Mon Aug 31 15:33:37 2026 node /usr/bin/node --max-old-space-size=1700 /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {"id":"Messwerte.0.HardwareDaten.Master.Speicher.memBuffered","path":"/mnt/usbplatte/data/history/","start":1788161558741,"end":1788183158741,"count":300,"from":false,"ack":false,"q":false,"ignoreNull":false,"aggregate":"minmax","limit":300,"addId":false,"sessionId":1057,"returnNewestEntries":false,"integralInterpolation":null,"removeBorderValues":false,"logId":"Messwerte.0.HardwareDaten.Master.Speicher.memBuffered17881832179950.6046703034490128","round":null,"logDebug":false}davon gibt es noch mehr zeilen und wahrscheinlich sind das nicht alle, da das skript nur die ersten paar aufzeichnet.
jede zeile ist ein eigener task
den einzigen kandidaten hab ich hier gefunden
https://github.com/ioBroker/ioBroker.history/blob/6957d59c009494caf798bea9fb32fe57c8b17f53/src/lib/getHistory.ts#L142
da scheint wohl node solche operationen als eigenen task auszuführen.
Das ist die Stelle bei der der history adapter die tagesdatei zu einem Datenpunkt liest.aber wie weiter oben schon mal erwähnt und zu überprüfen:
zeichnest du insbesondere bei den speicherrelevanten datenpunkten JEDE Änderung auf?
ich weiß nicht in welchem zeittakt der iobroker intern die datenpunkte aktualisiert. die gehen dann ja auch in die history und wenn da alle paar millisekunden bzw 100 millisekunden eine änderung gibt, dann werden entsprechend viele dateien geöffnet.
gut der history adapter sammelt ein wenig die daten in einem cache, aber wenn der voll ist, muss er schreiben. -
da scheint wohl node solche operationen als eigenen task auszuführen.
Aaah, das passt!
Unter top tauchte ab und zu ei prozess "node" auf und verschwand sofort wieder
die gehen dann ja auch in die history und wenn da alle paar millisekunden bzw 100 millisekunden
Nein, die sind nur höchstens alkec6 Sekunden.
Da müsste ich die system.host und system.adapter DP sicherheitshalber mal mit einer Blockzeit belegen!
Danke für den Tippda war jetzt nur das um 1605 mit dem neuen skript von den snapshots.
Dann hab ich vielleicht die falschen hochgeladen.
Muss ich checken und tausche ggf. Aussende insbesondere die snapshot, die größer wie 200k sind.
wenn ein oom kill dabei ist umso besserOk!
Damit kann ich was anfangenNein, die sind nur höchstens alkec6 Sekunden.
hm, du siehst allein in dem kleinen ausschnitt den ich beispielhaft gepostet habe ist mehrfach
system.host.ioBrokerpi5.freemem
Messwerte.0.HardwareDaten.Master.Speicher.mem_free
Messwerte.0.HardwareDaten.Master.Speicher.memBuffered
alles in der gleichen sekunde enthalten.
der exakte trigger lässt sich nicht ermitteln, da ja einmal der history adapter wegen schreiben liest und aber auch deine diagramme (womöglich in mehreren diagrammen den gleichen datenpunkt mehrfach) ebenfalls lesen.
aber alle fragen die history adapter funktionalitätich will es nur nochmal erwähnen. eine datenbank für die history werte würde das wahrscheinlich entschärfen.
aber jetzt schauen wir mal auf die nächsten snapshots bevor man vorschnell entscheidungen trifft. passe erst mal auch NICHT den history intervall deiner datenpunkte an, sonst ist ggfs die grundlage der analyse weg um entscheiden zu können.
-
da scheint wohl node solche operationen als eigenen task auszuführen.
Aaah, das passt!
Unter top tauchte ab und zu ei prozess "node" auf und verschwand sofort wieder
die gehen dann ja auch in die history und wenn da alle paar millisekunden bzw 100 millisekunden
Nein, die sind nur höchstens alkec6 Sekunden.
Da müsste ich die system.host und system.adapter DP sicherheitshalber mal mit einer Blockzeit belegen!
Danke für den Tippda war jetzt nur das um 1605 mit dem neuen skript von den snapshots.
Dann hab ich vielleicht die falschen hochgeladen.
Muss ich checken und tausche ggf. Aussende insbesondere die snapshot, die größer wie 200k sind.
wenn ein oom kill dabei ist umso besserOk!
Damit kann ich was anfangen -
@Homoran [sagte]: Unter top tauchte ab und zu ei prozess "node" auf und verschwand sofort wieder
Das passiert immer dann, wenn "node" einen neuen Prozess (Instanz / Skript) compiliert und startet.
-
Nein, die sind nur höchstens alkec6 Sekunden.
hm, du siehst allein in dem kleinen ausschnitt den ich beispielhaft gepostet habe ist mehrfach
system.host.ioBrokerpi5.freemem
Messwerte.0.HardwareDaten.Master.Speicher.mem_free
Messwerte.0.HardwareDaten.Master.Speicher.memBuffered
alles in der gleichen sekunde enthalten.
der exakte trigger lässt sich nicht ermitteln, da ja einmal der history adapter wegen schreiben liest und aber auch deine diagramme (womöglich in mehreren diagrammen den gleichen datenpunkt mehrfach) ebenfalls lesen.
aber alle fragen die history adapter funktionalitätich will es nur nochmal erwähnen. eine datenbank für die history werte würde das wahrscheinlich entschärfen.
aber jetzt schauen wir mal auf die nächsten snapshots bevor man vorschnell entscheidungen trifft. passe erst mal auch NICHT den history intervall deiner datenpunkte an, sonst ist ggfs die grundlage der analyse weg um entscheiden zu können.
hm, du siehst allein in dem kleinen ausschnitt den ich beispielhaft gepostet habe ist mehrfach
system.host.ioBrokerpi5.freemem
Messwerte.0.HardwareDaten.Master.Speicher.mem_free
Messwerte.0.HardwareDaten.Master.Speicher.memBufferedDie rufe ich per 15sec. Cron und dann mit exec ab.

Wo die mehrfach pro sekunde herkommen ist mir schleierhaftEdit:
Lesen in der history ist möglich.
Könnte das beim zoomen passieren.......oder eventuell bei mehrfachem Einlesen, weil der Browser Kontakt verliert
Auch die sockets wurden mehrfach pro sekunde neu verbunden -
hm, du siehst allein in dem kleinen ausschnitt den ich beispielhaft gepostet habe ist mehrfach
system.host.ioBrokerpi5.freemem
Messwerte.0.HardwareDaten.Master.Speicher.mem_free
Messwerte.0.HardwareDaten.Master.Speicher.memBufferedDie rufe ich per 15sec. Cron und dann mit exec ab.

Wo die mehrfach pro sekunde herkommen ist mir schleierhaftEdit:
Lesen in der history ist möglich.
Könnte das beim zoomen passieren.......oder eventuell bei mehrfachem Einlesen, weil der Browser Kontakt verliert
Auch die sockets wurden mehrfach pro sekunde neu verbundenich weiß nicht wie die diagramme auf aktualisierung der datenpunkte reagieren.
zu vermuten ist, das wenn sich der datenpunkt ändert, das diagramm die history abruft. wenn der datenpunkt in mehreren diagrammen auftaucht, dann sind das auch verschiedene lesevorgänge. -
ich weiß nicht wie die diagramme auf aktualisierung der datenpunkte reagieren.
zu vermuten ist, das wenn sich der datenpunkt ändert, das diagramm die history abruft. wenn der datenpunkt in mehreren diagrammen auftaucht, dann sind das auch verschiedene lesevorgänge.ich weiß nicht wie die diagramme auf aktualisierung der datenpunkte reagieren.
zu vermuten ist, das wenn sich der datenpunkt ändert, das diagramm die history abruft. wenn der datenpunkt in mehreren diagrammen auftaucht, dann sind das auch verschiedene lesevorgängeJein!
Du kannst in den charts einen Zeitraum für den refresh einstellen.Natürlich wird beim neuladen/zoomen auch neu abgerufen, weil auch anders aggregiert wird.
Das hat immer schon zu mehr Last geführt.
Bei sehr komplexen Charts und mehreren Zoomversuchen am Tablet/Handy ist es auch früher mal!! zum Absturz gekommen.
Aber vielleicht 2x im Jahr!Im Moment spiele ich natürlich viel an den Charts, um Zusammenhänge zu sehen.
Das lenkt dann vielleicht vom eigentlichen Problem ab.
Da sollten wir nur Drops beachten, die nachts passieren.Hier die letzten 3 ganz großen Snapshots
snapshot_20260831_162341.log snapshot_20260831_162442.log snapshot_20260831_163935.log -
ich weiß nicht wie die diagramme auf aktualisierung der datenpunkte reagieren.
zu vermuten ist, das wenn sich der datenpunkt ändert, das diagramm die history abruft. wenn der datenpunkt in mehreren diagrammen auftaucht, dann sind das auch verschiedene lesevorgängeJein!
Du kannst in den charts einen Zeitraum für den refresh einstellen.Natürlich wird beim neuladen/zoomen auch neu abgerufen, weil auch anders aggregiert wird.
Das hat immer schon zu mehr Last geführt.
Bei sehr komplexen Charts und mehreren Zoomversuchen am Tablet/Handy ist es auch früher mal!! zum Absturz gekommen.
Aber vielleicht 2x im Jahr!Im Moment spiele ich natürlich viel an den Charts, um Zusammenhänge zu sehen.
Das lenkt dann vielleicht vom eigentlichen Problem ab.
Da sollten wir nur Drops beachten, die nachts passieren.Hier die letzten 3 ganz großen Snapshots
snapshot_20260831_162341.log snapshot_20260831_162442.log snapshot_20260831_163935.log -
@OliverIO hier
1853memory.log -
@OliverIO hier
1853memory.logalso mit meiner Vermutung lag ich richtig.
hier die Analyse.
Ich habe dem codex nichts von dem was ich vorhin geschrieben habe mitgeteilt. einfach nur hier neue dateien.hast du mehrere browserclients laufen?
jeder fragt natürlich auch wieder separat ab und löst eine neue getHistory aus.Folgeanalyse der memwatch-Daten vom 31.08.2026
Kurzfazit
Die neuen Snapshots identifizieren den Verursacher der Task- und
Speicherstürme eindeutig:io.history.0(PID 39891) startet gleichzeitig sehr viele separate
Node-Prozesse mitiobroker.history/build/lib/getHistory.js.Jeder dieser Prozesse besitzt typischerweise sieben Threads und ungefähr
40 bis 57 MB RSS. Bei 76 bis 156 gleichzeitig aktivengetHistory.js-Prozessen
entstehen deshalb innerhalb weniger Sekunden mehrere hundert bis über tausend
zusätzliche Tasks und ein Speicherbedarf von mehreren Gigabyte. Im zweiten
Snapshot sind zusätzlich 112 nicht abgeholte Zombie-Prozesse ([node] <defunct>) sichtbar.Der zuvor verdächtigte Adapter
dwd.0ist damit als Hauptursache widerlegt.
Die unmittelbare technische Ursache liegt im History-Adapter beziehungsweise
in einer extrem hohen Zahl paralleler History-Abfragen. Welcher Client oder
welches ioBroker-Script diese Abfragen auslöst, lässt sich aus den gelieferten
System-Snapshots allein noch nicht endgültig bestimmen.Ausgewertete neue Dateien
1788195273188-1853memory.log1788190003254-snapshot_20260831_162341.log1788190003258-snapshot_20260831_162442.log1788190003266-snapshot_20260831_163935.log
Das große
memory.logenthält zahlreiche weitere Trigger. Für drei Ereignisse
wurden detaillierte Snapshots mitgeliefert; diese drei erlauben die eindeutige
Prozesszuordnung.Übersicht der drei detaillierten Ereignisse
Snapshotzeit MemAvailable-Abfall Taskanstieg Tasks am Trigger aktive getHistory.jsZombies Threads der aktiven History-Children 16:23:42 1.859 MB +955 1.669 156 0 1.092 16:24:43 1.103 MB +525 1.239 76 112 532 16:39:36 1.283 MB +829 1.487 141 3 987 Die Zahlen passen sehr genau zusammen: 156 aktive Child-Prozesse mit jeweils
sieben Threads ergeben 1.092 Threads. Zusammen mit den ungefähr 700 normalen
Systemtasks erklärt das vollständig die am Trigger beziehungsweise unmittelbar
danach beobachtete Größenordnung.Eindeutige Parent-Zuordnung
In allen drei Soforterfassungen ist der Parent der massenhaft erzeugten
Prozesse:PID 39891 io.history.0Beispiele seiner Children sehen so aus:
/usr/bin/node --max-old-space-size=1700 \ /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {...}Die Parent-Gruppierung ergibt:
- um 16:23:42: 156 Prozesse mit PPID 39891,
- um 16:24:43: 188 Prozesse mit PPID 39891,
- um 16:39:36: 144 Prozesse mit PPID 39891.
Beim mittleren Snapshot bestehen diese 188 Children aus 76 noch aktiven
getHistory.js-Prozessen und 112 Zombies. Das beweist auch, dass der
History-Prozess zu diesem Zeitpunkt beendete Child-Prozesse nicht schnell genug
mitwait()beziehungsweise über seinen Child-Exit-Handler aufgeräumt hatte.Speicherwirkung
Die aufsummierten RSS-Werte der aktiven
getHistory.js-Prozesse betragen in den
drei Soforterfassungen rechnerisch ungefähr:- 8.171 MB bei 156 aktiven Prozessen,
- 3.828 MB bei 76 aktiven Prozessen,
- 7.094 MB bei 141 aktiven Prozessen.
Diese RSS-Summen dürfen wegen gemeinsam genutzter Speicherseiten nicht als
exakter physischer RAM-Verbrauch interpretiert werden. Die gleichzeitig
gemessenen realen Einbrüche vonMemAvailableum 1,1 bis 1,9 GB zeigen aber,
dass ein großer privater Speicheranteil tatsächlich angelegt wird. Die
Parallelität reicht auf dem 8-GB-System aus, um die früher beobachteten
OOM-Ereignisse zu erklären.Jeder Child-Prozess darf außerdem mit folgendem Parameter theoretisch einen
sehr großen Node-Heap anlegen:--max-old-space-size=1700Ein einzelner Prozess nutzt dieses Maximum hier nicht aus. Bei über hundert
gleichzeitigen Prozessen ist diese Konfiguration jedoch keine wirksame
Gesamtbegrenzung.Muster der History-Abfragen
Es handelt sich nicht um einzelne, sehr große Abfragen, sondern um viele
parallel wiederholte Abfragen. Typische Parameter sind:{ "count": 1500, "aggregate": "minmax", "limit": 1500, "start": 1788127200000, "end": 1788213600000 }Mehrere identische Datenpunkte werden gleichzeitig oder in rasch aufeinander
folgenden Sessions wiederholt abgefragt. Beispiele aus den Snapshots:system.host.ioBrokerpi5.freememsystem.host.ioBrokerpi5.inputCountsystem.host.ioBrokerpi5.outputCountsystem.host.ioBrokerpi5.loadsystem.adapter.javascript.1.inputCountsystem.adapter.javascript.1.outputCountMesswerte.0.HardwareDaten.Master.CPU_Last.CPU_TempMesswerte.0.Solaranlage.Momentanwerte.Solarestimate2Messwerte.0.Solaranlage.Momentanwerte.Leistung_AC_aktuellMesswerte.0.Solaranlage.Momentanwerte.EigenverbrauchMesswerte.0.Stromzaehler.Momentanwerte.akt_VerbrauchMesswerte.0.Stromzaehler.Momentanwerte.akt_EinspeisungMesswerte.0.Batterie.LadungMesswerte.0.Batterie.Entladungalias.0.Stromzaehler.Bezug_aktuellmodbus.1.inputRegisters.226.789_Solar_PV_power
Im Snapshot um 16:39 werden beispielsweise sieben System-/Hardware-Datenpunkte
jeweils ungefähr 19- bis 20-mal parallel angefragt. In den Prozessargumenten
steigen dabei auch diesessionId-Werte fortlaufend an. Das sieht nach
wiederholten Anfragegruppen eines Dashboards, Diagramms oder Scripts aus und
nicht nach einer normalen Einzelabfrage.Ursache und Auslöser getrennt betrachtet
Technische Ursache: bestätigt
Der History-Adapter erzeugt für jede History-Abfrage einen eigenen
getHistory.js-Child-Prozess. Zu viele gleichzeitige Abfragen führen direkt zu:- hunderten Node-Prozessen,
- sieben Threads pro aktivem Prozess,
- massiv steigenden
PageTablesundKernelStack, - mehreren Gigabyte zusätzlichem Speicherbedarf,
- kurzzeitig hoher CPU- und I/O-Last,
- Zombies, wenn Children schneller enden als sie abgeholt werden,
- im Extremfall OOM-Kills.
Anfragender Client: noch nicht abschließend identifiziert
PPID 39891 beweist, dass
io.history.0die Prozesse startet. Die Argumente der
Children enthalten jedoch nicht den Namen des Clients, der die History-Anfrage
an den Adapter geschickt hat. Wahrscheinliche Quellen sind:- ein geöffnetes VIS-/VIS-2-Dashboard mit vielen oder zyklisch neu gerenderten
Diagrammen, - ein Flot-/ECharts-/Chart-Widget mit zu kurzem Refresh-Intervall,
- ein JavaScript unter
javascript.1, das vielegetHistory-Aufrufe startet,
ohne deren Abschluss abzuwarten, - eine Schleife oder ein mehrfach registrierter Timer/Listener, der dieselben
Abfragegruppen immer wieder startet.
Die Datenpunktgruppen wirken wie Dashboard- oder Energievisualisierungsdaten.
Das ist ein starker Hinweis, aber noch kein Beweis für einen bestimmten Client.Korrektur der vorherigen Bewertung
In der ersten Analyse war
dwd.0aufgrund seines Startzeitpunkts der stärkste
damals sichtbare Verdächtige. Die frühere Threadliste kam zu spät und war zudem
teilweise leer. Die reparierte Soforterfassung zeigt nun den tatsächlichen
Mechanismus.dwd.0erklärt die neuen Peaks nicht; seine zeitliche Nähe im
früheren Snapshot war eine Korrelation ohne Kausalitätsnachweis.Dringend empfohlene Maßnahmen
1. System kurzfristig stabilisieren
- Betroffene Visualisierung beziehungsweise das verdächtige Script schließen
oder deaktivieren. - Falls der Sturm gerade läuft,
io.history.0kontrolliert neu starten, damit
aktive Children und Zombies verschwinden. - Danach beobachten, ob die Taskzahl wieder stabil bei ungefähr 650 bis 720
bleibt.
Ein Neustart behandelt nur die Symptome. Ohne Beseitigung des Anfrageerzeugers
wird der Sturm erneut auftreten.2. Anfragequelle per A/B-Test ermitteln
In dieser Reihenfolge jeweils nur eine Änderung vornehmen und
memory.log
beobachten:- Alle Browser mit ioBroker-Visualisierungen schließen.
- Falls die Peaks aufhören, Browser/Views einzeln wieder öffnen.
- Falls sie weiterlaufen, verdächtige JavaScript-Instanz beziehungsweise
einzelne Scripts deaktivieren. - Besonders nach Scripts suchen, die
sendTo('history.0', 'getHistory', ...),
getHistory(...)oder periodische Chart-Aktualisierungen verwenden. - Timer,
setInterval, State-Subscriptions und rekursive Aktualisierungen
darauf prüfen, ob bei jedem Lauf neue Abfragen gestartet werden, bevor alte
abgeschlossen sind.
3. Parallelität begrenzen
Beim eigentlichen Aufrufer sollten History-Abfragen:
- nicht mehrfach parallel für denselben Datenpunkt laufen,
- erst nach Abschluss der vorherigen Anfrage erneut gestartet werden,
- in einer begrenzten Queue verarbeitet werden,
- gecacht oder zusammengefasst werden,
- mit einem deutlich längeren Aktualisierungsintervall laufen.
Schon eine Begrenzung auf wenige gleichzeitige Abfragen würde den Task- und
Speicherpeak drastisch reduzieren.4. History-Adapter prüfen und aktualisieren
- Installierte Version von
iobroker.historyfeststellen. - Changelog und bekannte Probleme dieser konkreten Version bezüglich
getHistory.js, Child-Prozessen, Parallelität und Zombies prüfen. - Ein Update erst nach Versions- und Kompatibilitätsprüfung durchführen.
Die Systemdaten belegen eine problematische Last, sagen aber nicht, ob die
eingesetzte Adapterversion bereits eine eingebaute Parallelitätsbegrenzung
anbietet oder ob es dazu einen bekannten Fix gibt.Sinnvolle Zusatzdiagnose
Für die eindeutige Identifikation des anfragenden Clients sollten unmittelbar
um einen Peak zusätzlich gesichert werden:iobroker logs --watchund gezielt:
grep -RniE "getHistory|sendTo.*history\.0|history\.0.*getHistory" \ /opt/iobroker/iobroker-data/files \ /opt/iobroker/node_modules 2>/dev/nullBei JavaScript-Quelltexten sollte bevorzugt über die ioBroker-Objekte oder den
Admin exportiert/gesucht werden, weil nicht jedes Script als normale Datei
vorliegt.Zusätzlich wäre eine kurze Liste der geöffneten VIS-Views und der aktiven
Chart-Widgets zum Peakzeitpunkt hilfreich. Die im Prozessargument sichtbaren
sessionId-Gruppen könnten dann einer konkreten Browser-/Widget-Sitzung
zugeordnet werden, sofern der Adapter im Debug-Log die Session protokolliert.Endergebnis
Die Diagnose ist jetzt wesentlich belastbarer als zuvor. Es handelt sich nicht
um einen einzelnen Node-Prozess mit tausenden Threads, sondern um einen
Prozesssturm aus bis zu 156 gleichzeitig aktivengetHistory.js-Prozessen.
Diese werden alle vonio.history.0erzeugt und besitzen jeweils sieben
Threads. Wiederholte parallele History-Anfragegruppen sind damit die bestätigte
Ursache für die Task-, PageTable-, KernelStack- und RAM-Spitzen.Der nächste Untersuchungsschritt sollte nicht mehr allgemein nach einem
Speicherleck suchen, sondern gezielt den Client beziehungsweise das Script
finden, das diese History-Abfragen in hoher Parallelität auslöst. -
also mit meiner Vermutung lag ich richtig.
hier die Analyse.
Ich habe dem codex nichts von dem was ich vorhin geschrieben habe mitgeteilt. einfach nur hier neue dateien.hast du mehrere browserclients laufen?
jeder fragt natürlich auch wieder separat ab und löst eine neue getHistory aus.Folgeanalyse der memwatch-Daten vom 31.08.2026
Kurzfazit
Die neuen Snapshots identifizieren den Verursacher der Task- und
Speicherstürme eindeutig:io.history.0(PID 39891) startet gleichzeitig sehr viele separate
Node-Prozesse mitiobroker.history/build/lib/getHistory.js.Jeder dieser Prozesse besitzt typischerweise sieben Threads und ungefähr
40 bis 57 MB RSS. Bei 76 bis 156 gleichzeitig aktivengetHistory.js-Prozessen
entstehen deshalb innerhalb weniger Sekunden mehrere hundert bis über tausend
zusätzliche Tasks und ein Speicherbedarf von mehreren Gigabyte. Im zweiten
Snapshot sind zusätzlich 112 nicht abgeholte Zombie-Prozesse ([node] <defunct>) sichtbar.Der zuvor verdächtigte Adapter
dwd.0ist damit als Hauptursache widerlegt.
Die unmittelbare technische Ursache liegt im History-Adapter beziehungsweise
in einer extrem hohen Zahl paralleler History-Abfragen. Welcher Client oder
welches ioBroker-Script diese Abfragen auslöst, lässt sich aus den gelieferten
System-Snapshots allein noch nicht endgültig bestimmen.Ausgewertete neue Dateien
1788195273188-1853memory.log1788190003254-snapshot_20260831_162341.log1788190003258-snapshot_20260831_162442.log1788190003266-snapshot_20260831_163935.log
Das große
memory.logenthält zahlreiche weitere Trigger. Für drei Ereignisse
wurden detaillierte Snapshots mitgeliefert; diese drei erlauben die eindeutige
Prozesszuordnung.Übersicht der drei detaillierten Ereignisse
Snapshotzeit MemAvailable-Abfall Taskanstieg Tasks am Trigger aktive getHistory.jsZombies Threads der aktiven History-Children 16:23:42 1.859 MB +955 1.669 156 0 1.092 16:24:43 1.103 MB +525 1.239 76 112 532 16:39:36 1.283 MB +829 1.487 141 3 987 Die Zahlen passen sehr genau zusammen: 156 aktive Child-Prozesse mit jeweils
sieben Threads ergeben 1.092 Threads. Zusammen mit den ungefähr 700 normalen
Systemtasks erklärt das vollständig die am Trigger beziehungsweise unmittelbar
danach beobachtete Größenordnung.Eindeutige Parent-Zuordnung
In allen drei Soforterfassungen ist der Parent der massenhaft erzeugten
Prozesse:PID 39891 io.history.0Beispiele seiner Children sehen so aus:
/usr/bin/node --max-old-space-size=1700 \ /opt/iobroker/node_modules/iobroker.history/build/lib/getHistory.js {...}Die Parent-Gruppierung ergibt:
- um 16:23:42: 156 Prozesse mit PPID 39891,
- um 16:24:43: 188 Prozesse mit PPID 39891,
- um 16:39:36: 144 Prozesse mit PPID 39891.
Beim mittleren Snapshot bestehen diese 188 Children aus 76 noch aktiven
getHistory.js-Prozessen und 112 Zombies. Das beweist auch, dass der
History-Prozess zu diesem Zeitpunkt beendete Child-Prozesse nicht schnell genug
mitwait()beziehungsweise über seinen Child-Exit-Handler aufgeräumt hatte.Speicherwirkung
Die aufsummierten RSS-Werte der aktiven
getHistory.js-Prozesse betragen in den
drei Soforterfassungen rechnerisch ungefähr:- 8.171 MB bei 156 aktiven Prozessen,
- 3.828 MB bei 76 aktiven Prozessen,
- 7.094 MB bei 141 aktiven Prozessen.
Diese RSS-Summen dürfen wegen gemeinsam genutzter Speicherseiten nicht als
exakter physischer RAM-Verbrauch interpretiert werden. Die gleichzeitig
gemessenen realen Einbrüche vonMemAvailableum 1,1 bis 1,9 GB zeigen aber,
dass ein großer privater Speicheranteil tatsächlich angelegt wird. Die
Parallelität reicht auf dem 8-GB-System aus, um die früher beobachteten
OOM-Ereignisse zu erklären.Jeder Child-Prozess darf außerdem mit folgendem Parameter theoretisch einen
sehr großen Node-Heap anlegen:--max-old-space-size=1700Ein einzelner Prozess nutzt dieses Maximum hier nicht aus. Bei über hundert
gleichzeitigen Prozessen ist diese Konfiguration jedoch keine wirksame
Gesamtbegrenzung.Muster der History-Abfragen
Es handelt sich nicht um einzelne, sehr große Abfragen, sondern um viele
parallel wiederholte Abfragen. Typische Parameter sind:{ "count": 1500, "aggregate": "minmax", "limit": 1500, "start": 1788127200000, "end": 1788213600000 }Mehrere identische Datenpunkte werden gleichzeitig oder in rasch aufeinander
folgenden Sessions wiederholt abgefragt. Beispiele aus den Snapshots:system.host.ioBrokerpi5.freememsystem.host.ioBrokerpi5.inputCountsystem.host.ioBrokerpi5.outputCountsystem.host.ioBrokerpi5.loadsystem.adapter.javascript.1.inputCountsystem.adapter.javascript.1.outputCountMesswerte.0.HardwareDaten.Master.CPU_Last.CPU_TempMesswerte.0.Solaranlage.Momentanwerte.Solarestimate2Messwerte.0.Solaranlage.Momentanwerte.Leistung_AC_aktuellMesswerte.0.Solaranlage.Momentanwerte.EigenverbrauchMesswerte.0.Stromzaehler.Momentanwerte.akt_VerbrauchMesswerte.0.Stromzaehler.Momentanwerte.akt_EinspeisungMesswerte.0.Batterie.LadungMesswerte.0.Batterie.Entladungalias.0.Stromzaehler.Bezug_aktuellmodbus.1.inputRegisters.226.789_Solar_PV_power
Im Snapshot um 16:39 werden beispielsweise sieben System-/Hardware-Datenpunkte
jeweils ungefähr 19- bis 20-mal parallel angefragt. In den Prozessargumenten
steigen dabei auch diesessionId-Werte fortlaufend an. Das sieht nach
wiederholten Anfragegruppen eines Dashboards, Diagramms oder Scripts aus und
nicht nach einer normalen Einzelabfrage.Ursache und Auslöser getrennt betrachtet
Technische Ursache: bestätigt
Der History-Adapter erzeugt für jede History-Abfrage einen eigenen
getHistory.js-Child-Prozess. Zu viele gleichzeitige Abfragen führen direkt zu:- hunderten Node-Prozessen,
- sieben Threads pro aktivem Prozess,
- massiv steigenden
PageTablesundKernelStack, - mehreren Gigabyte zusätzlichem Speicherbedarf,
- kurzzeitig hoher CPU- und I/O-Last,
- Zombies, wenn Children schneller enden als sie abgeholt werden,
- im Extremfall OOM-Kills.
Anfragender Client: noch nicht abschließend identifiziert
PPID 39891 beweist, dass
io.history.0die Prozesse startet. Die Argumente der
Children enthalten jedoch nicht den Namen des Clients, der die History-Anfrage
an den Adapter geschickt hat. Wahrscheinliche Quellen sind:- ein geöffnetes VIS-/VIS-2-Dashboard mit vielen oder zyklisch neu gerenderten
Diagrammen, - ein Flot-/ECharts-/Chart-Widget mit zu kurzem Refresh-Intervall,
- ein JavaScript unter
javascript.1, das vielegetHistory-Aufrufe startet,
ohne deren Abschluss abzuwarten, - eine Schleife oder ein mehrfach registrierter Timer/Listener, der dieselben
Abfragegruppen immer wieder startet.
Die Datenpunktgruppen wirken wie Dashboard- oder Energievisualisierungsdaten.
Das ist ein starker Hinweis, aber noch kein Beweis für einen bestimmten Client.Korrektur der vorherigen Bewertung
In der ersten Analyse war
dwd.0aufgrund seines Startzeitpunkts der stärkste
damals sichtbare Verdächtige. Die frühere Threadliste kam zu spät und war zudem
teilweise leer. Die reparierte Soforterfassung zeigt nun den tatsächlichen
Mechanismus.dwd.0erklärt die neuen Peaks nicht; seine zeitliche Nähe im
früheren Snapshot war eine Korrelation ohne Kausalitätsnachweis.Dringend empfohlene Maßnahmen
1. System kurzfristig stabilisieren
- Betroffene Visualisierung beziehungsweise das verdächtige Script schließen
oder deaktivieren. - Falls der Sturm gerade läuft,
io.history.0kontrolliert neu starten, damit
aktive Children und Zombies verschwinden. - Danach beobachten, ob die Taskzahl wieder stabil bei ungefähr 650 bis 720
bleibt.
Ein Neustart behandelt nur die Symptome. Ohne Beseitigung des Anfrageerzeugers
wird der Sturm erneut auftreten.2. Anfragequelle per A/B-Test ermitteln
In dieser Reihenfolge jeweils nur eine Änderung vornehmen und
memory.log
beobachten:- Alle Browser mit ioBroker-Visualisierungen schließen.
- Falls die Peaks aufhören, Browser/Views einzeln wieder öffnen.
- Falls sie weiterlaufen, verdächtige JavaScript-Instanz beziehungsweise
einzelne Scripts deaktivieren. - Besonders nach Scripts suchen, die
sendTo('history.0', 'getHistory', ...),
getHistory(...)oder periodische Chart-Aktualisierungen verwenden. - Timer,
setInterval, State-Subscriptions und rekursive Aktualisierungen
darauf prüfen, ob bei jedem Lauf neue Abfragen gestartet werden, bevor alte
abgeschlossen sind.
3. Parallelität begrenzen
Beim eigentlichen Aufrufer sollten History-Abfragen:
- nicht mehrfach parallel für denselben Datenpunkt laufen,
- erst nach Abschluss der vorherigen Anfrage erneut gestartet werden,
- in einer begrenzten Queue verarbeitet werden,
- gecacht oder zusammengefasst werden,
- mit einem deutlich längeren Aktualisierungsintervall laufen.
Schon eine Begrenzung auf wenige gleichzeitige Abfragen würde den Task- und
Speicherpeak drastisch reduzieren.4. History-Adapter prüfen und aktualisieren
- Installierte Version von
iobroker.historyfeststellen. - Changelog und bekannte Probleme dieser konkreten Version bezüglich
getHistory.js, Child-Prozessen, Parallelität und Zombies prüfen. - Ein Update erst nach Versions- und Kompatibilitätsprüfung durchführen.
Die Systemdaten belegen eine problematische Last, sagen aber nicht, ob die
eingesetzte Adapterversion bereits eine eingebaute Parallelitätsbegrenzung
anbietet oder ob es dazu einen bekannten Fix gibt.Sinnvolle Zusatzdiagnose
Für die eindeutige Identifikation des anfragenden Clients sollten unmittelbar
um einen Peak zusätzlich gesichert werden:iobroker logs --watchund gezielt:
grep -RniE "getHistory|sendTo.*history\.0|history\.0.*getHistory" \ /opt/iobroker/iobroker-data/files \ /opt/iobroker/node_modules 2>/dev/nullBei JavaScript-Quelltexten sollte bevorzugt über die ioBroker-Objekte oder den
Admin exportiert/gesucht werden, weil nicht jedes Script als normale Datei
vorliegt.Zusätzlich wäre eine kurze Liste der geöffneten VIS-Views und der aktiven
Chart-Widgets zum Peakzeitpunkt hilfreich. Die im Prozessargument sichtbaren
sessionId-Gruppen könnten dann einer konkreten Browser-/Widget-Sitzung
zugeordnet werden, sofern der Adapter im Debug-Log die Session protokolliert.Endergebnis
Die Diagnose ist jetzt wesentlich belastbarer als zuvor. Es handelt sich nicht
um einen einzelnen Node-Prozess mit tausenden Threads, sondern um einen
Prozesssturm aus bis zu 156 gleichzeitig aktivengetHistory.js-Prozessen.
Diese werden alle vonio.history.0erzeugt und besitzen jeweils sieben
Threads. Wiederholte parallele History-Anfragegruppen sind damit die bestätigte
Ursache für die Task-, PageTable-, KernelStack- und RAM-Spitzen.Der nächste Untersuchungsschritt sollte nicht mehr allgemein nach einem
Speicherleck suchen, sondern gezielt den Client beziehungsweise das Script
finden, das diese History-Abfragen in hoher Parallelität auslöst.sondern gezielt den Client beziehungsweise das Script
finden, das diese History-Abfragen in hoher Parallelität auslöst.Üblicherweise ist das ein Client.
Deswegen irritiert mich das so.
Das hat jahrelang so funktioniert.
Außerdem:system.host.ioBrokerpi5.freemem
system.host.ioBrokerpi5.inputCountsystem.adapter.javascript.1.inputCount
system.adapter.javascript.1.outputCountSind erst nach dem Auftreten der Probleme hinzugekommen!
jeweils ungefähr 19- bis 20-mal parallel angefragt
Dafür habe ich keine Erklärung
Auch nicht dass der Absturz üblicherweise stattfindet wenn kein client aktiv ist.
Wie ich ganz zu Beginn schon zeigte

Verbindet/trennt sich der client (...116, das ist mein Tablet) auch mehrfach pro Sekunde.
Das wäre vielleicht die Ursache der im log festgehaltenen Phänomene, ohne dass das die wirklichen Ursachen sind.Ich bin ratlos
-
sondern gezielt den Client beziehungsweise das Script
finden, das diese History-Abfragen in hoher Parallelität auslöst.Üblicherweise ist das ein Client.
Deswegen irritiert mich das so.
Das hat jahrelang so funktioniert.
Außerdem:system.host.ioBrokerpi5.freemem
system.host.ioBrokerpi5.inputCountsystem.adapter.javascript.1.inputCount
system.adapter.javascript.1.outputCountSind erst nach dem Auftreten der Probleme hinzugekommen!
jeweils ungefähr 19- bis 20-mal parallel angefragt
Dafür habe ich keine Erklärung
Auch nicht dass der Absturz üblicherweise stattfindet wenn kein client aktiv ist.
Wie ich ganz zu Beginn schon zeigte

Verbindet/trennt sich der client (...116, das ist mein Tablet) auch mehrfach pro Sekunde.
Das wäre vielleicht die Ursache der im log festgehaltenen Phänomene, ohne dass das die wirklichen Ursachen sind.Ich bin ratlos
um clients dann ausschließen mal eine weile alle browser tabs auf allen geräten mit iobroker schließen und schauen ob diese große Anzahl an threads noch auftauchen.
du nutzt vis1 oder vis2 als visualisierung?
dann auch mal PC browser und tablet vergleichen. also nur PC browser geöffnet und tablet nicht und umgekehrt.
Nicht das bspw das tablet ständig in schlafmodus geht und gleich wieder aufwacht. das löst evtl auch eine aktualisierung aus.
jeder einzelne tab zählt auch als separater client -
um clients dann ausschließen mal eine weile alle browser tabs auf allen geräten mit iobroker schließen und schauen ob diese große Anzahl an threads noch auftauchen.
du nutzt vis1 oder vis2 als visualisierung?
dann auch mal PC browser und tablet vergleichen. also nur PC browser geöffnet und tablet nicht und umgekehrt.
Nicht das bspw das tablet ständig in schlafmodus geht und gleich wieder aufwacht. das löst evtl auch eine aktualisierung aus.
jeder einzelne tab zählt auch als separater clientum clients dann ausschließen mal eine weile alle browser tabs auf allen geräten mit iobroker schließen und schauen ob diese große Anzahl an threads noch auftauchen
Mach ich, aber nicht sofort.
Erst nach dem nächsten Absturz.Dazu eine Verständnisfrage:
- Werden alle views eines Projekts beim öffnen von vis im Hintergrund geladen?
- werden alle Tabs eines Browsers beim öffnen des Browsers im Hintergrund geladen?
Üblicherweise öffne ich zwei views in denen kein oder drei charts sind.
Nur bei Nachfragen öffne ich Detailseiten mit charts.Jetzt während der Gehletsuche halte ich 3-5 weitere Tabs mit je einem flotchart vor. Öffnen nur bei bedarf.
Die genannten Datenpunkte kommen dort vor!
Ich hatte auch schon an das letzte Update des Browsers als Ursache gedacht.
Erklärt aber alles einen Absturz während der Ruhezeit nicht!
du nutzt vis1
nur PC browser
Isch 'abe kein pezeh!
Nur Täblettjeder einzelne tab zählt auch als separater client
Ok!
Siehe obenDANKE!
Hey! Du scheinst an dieser Unterhaltung interessiert zu sein, hast aber noch kein Konto.
Hast du es satt, bei jedem Besuch durch die gleichen Beiträge zu scrollen? Wenn du dich für ein Konto anmeldest, kommst du immer genau dorthin zurück, wo du zuvor warst, und kannst dich über neue Antworten benachrichtigen lassen (entweder per E-Mail oder Push-Benachrichtigung). Du kannst auch Lesezeichen speichern und Beiträge positiv bewerten, um anderen Community-Mitgliedern deine Wertschätzung zu zeigen.
Mit deinem Input könnte dieser Beitrag noch besser werden 💗
Registrieren Anmelden
sind sie alle bisher!