Zurück zum Blog
·8 Min. Lesezeit·productdevbook

Warum Hilfsprozesse macOS-Bandbreiten-Monitore verwirren

Hilfsprozesse zerlegen eine sichtbare App in ein Dutzend Netzwerk-Zeilen. Warum das unter macOS passiert und wie Sie darüber hinweg lesen.

  • macOS
  • Bandwidth
  • Network monitoring
  • Deep dive

Sie öffnen Activity Monitor an einem ruhigen Nachmittag, sortieren nach Netzwerk-Bytes, und die Spitze Ihrer Liste sieht so aus: Google Chrome Helper (Renderer), Google Chrome Helper (GPU), Google Chrome Helper, Slack Helper, Slack Helper (Renderer), Slack Helper (GPU). Es gibt keine Zeile für „Chrome" oder „Slack" — nur ein Konfetti aus Hilfsprozessen, jeder zieht ein paar hundert Kilobyte pro Sekunde. Welche App spricht eigentlich? Diese Verwirrung ist der ganze Grund, warum die Bandbreitenzuordnung von Mac-Hilfsprozessen der schwierigste Teil beim Bauen eines Netzwerkmonitors auf macOS ist.

Dieser Beitrag erklärt, warum Apps überhaupt Hilfsprozesse spawnen, warum der Kernel ihre Netzwerknutzung separat meldet und was „Folding" bedeutet, wenn ein Tool versucht, Ihnen eine saubere Pro-App-Zahl zu geben.

Warum Apps Hilfsprozesse spawnen

Moderne macOS-Apps laufen fast nie als ein einzelner Prozess. Es gibt drei große Gründe.

Sandboxing und Privilegien-Trennung

Apples App Sandbox ist eine Pro-Prozess-Grenze. Ein Renderer, der nicht vertrauenswürdiges HTML parst oder JavaScript ausführt, läuft mit anderen Entitlements als der Eltern, der Ihre Mikrofon-Berechtigung besitzt. Wenn der Renderer von einer bösartigen Seite kompromittiert wird, hört der Schadensradius bei diesem Prozess auf — er kann nicht plötzlich beginnen, Audio aufzuzeichnen oder Ihren Documents-Ordner zu lesen. Deshalb haben Chrome und Safari beide separate Prozesse für jeden Tab oder jede Seite, und deshalb folgen Slack, Discord und Notion (alles Electron-Apps) demselben Muster.

Crash-Isolation

Wenn ein Tab in Chrome an Speicher ausgeht oder einen JavaScript-Engine-Bug trifft, wollen Sie nicht, dass jeder Tab im Browser mit ihm stirbt. Hilfsprozesse bedeuten, dass eine schlechte Seite den „Aw, Snap"-Bildschirm für diesen Tab zeigt und nichts anderes. Dieselbe Logik gilt für Slack, das einen Channel rendert, oder Discord, das einen Voice-Anruf rendert.

Electron- und Chromium-Architektur

Wenn die App auf Electron gebaut ist — Slack, Discord, VS Code, Notion, Linear, Figma Desktop, 1Password 8, Microsoft Teams, Postman — erbt sie Chromiums Multi-Prozess-Modell vollständig. Es gibt einen „Main"-Prozess, einen „GPU"-Prozess, einen „Network Service"-Prozess (oft Utility genannt) und einen Renderer-Prozess pro Browserfenster oder bedeutsamer Sicht. Der Renderer öffnet selbst nie einen Socket. Er spricht über IPC zum Network-Service, und der Network-Service macht den eigentlichen TCP-Handshake.

Dieses letzte Detail zählt mehr, als es klingt.

Warum die Bandbreitenzuordnung von Mac-Hilfsprozessen schwer ist

Der macOS-Kernel ordnet Bytes derjenigen PID zu, die socket(2) und dann connect(2)/sendto(2)/recvfrom(2) aufgerufen hat. Das ist die richtige Antwort für den Kernel — er hat keine Ahnung, was „Slack" als Produkt bedeutet. Er weiß nur, dass PID 4711 einen Socket zu 34.117.x.x:443 geöffnet hat.

Wenn Sie also nettop oder lsof -i oder die rohe proc_pidinfo-API fragen „wer hat Netzwerk-Bytes genutzt", bekommen Sie eine flache Liste von PIDs zurück. Jede PID hat einen Prozessnamen (den Executable-Namen auf Disk), und dieser Name ist fast immer etwas wie:

  • Google Chrome Helper
  • Google Chrome Helper (GPU)
  • Google Chrome Helper (Renderer)
  • Google Chrome Helper (Plugin)
  • Slack Helper
  • Slack Helper (Renderer)
  • Slack Helper (GPU)
  • com.docker.backend

Ein naiver Monitor — einer, der einfach die Sicht des Kernels auf den Bildschirm dumpt — zeigt Ihnen genau das. Sie sehen sieben Chrome-Zeilen, die Sie mental aufaddieren müssen, um „wie viel hat Chrome diese Stunde genutzt?" zu beantworten. Schlimmer, die Renderer sind kurzlebig. Tab schließen, der Renderer stirbt. Einen neuen öffnen, ein neuer Renderer mit neuer PID erscheint. Über eine Stunde aufsummieren und die Antwort ist über Dutzende toter PIDs fragmentiert. Das ist die Kernherausforderung der Bandbreitenzuordnung von Mac-Hilfsprozessen: Die Einheiten, die der Kernel offenlegt, passen nicht zu den Einheiten, in denen ein Mensch denken möchte.

Was „Folding" bedeutet

Folding ist der Akt, einen Hilfsprozess anzuschauen — über seinen Bundle-Pfad, Eltern-PID oder beides — und seine Bytes der nutzersichtbaren App zuzuordnen, zu der er gehört. Richtig gemacht, hören Sie auf, elf Chrome-Zeilen zu sehen, und beginnen, eine Zeile namens „Google Chrome" mit der Summe zu sehen.

Es gibt ein paar Wege, das zu tun, und jeder hat Tradeoffs.

Über den Bundle-Pfad

Jeder Hilfsprozess lebt im Bundle der Eltern-App. Für Chrome ist dieser Pfad etwa:

/Applications/Google Chrome.app/Contents/Frameworks/
  Google Chrome Framework.framework/Versions/.../Helpers/
  Google Chrome Helper.app/Contents/MacOS/Google Chrome Helper

Wenn der Executable-Pfad eines Prozesses ein anderes .app-Bundle weiter oben im Baum enthält, ist das äußere Bundle fast sicher der Eltern. Das ist das verlässlichste Folding-Signal, weil es PID-Wechsel überlebt — neuen Chrome-Tab öffnen, der Pfad des neuen Renderers ist immer noch unter Google Chrome.app.

Über die Eltern-PID

Sie können den Prozessbaum hochlaufen, bis Sie auf einen Eltern treffen, der in /Applications lebt oder dessen Bundle-Identifier zu einer „echten" Anwendung passt. Das funktioniert, ist aber fragiler — launchd reparentet verwaiste Prozesse, und manche Hilfsprozesse werden von XPC-Services statt direkt vom Eltern gestartet.

Über das Bundle-Identifier-Präfix

Slacks Bundle-ID ist com.tinyspeck.slackmacgap. Die Bundle-ID des Helpers ist com.tinyspeck.slackmacgap.helper oder com.tinyspeck.slackmacgap.helper.renderer. Ein Präfix-Match gegen die Tabelle installierter Apps fängt die meisten Fälle. Das ist die Technik, die Apple intern für manche nutzersichtbaren Reports nutzt.

In der Praxis nutzt ein guter Monitor alle drei Signale und fällt elegant zurück, wenn eines fehlt.

Sehen Sie ova in Aktion

Ein auf einen Blick erfassbarer Menüleisten-Bandbreitenmonitor — lokal, signiert, ~3 MB.

Für macOS herunterladen

Der Electron-Sonderfall

Electron-Apps verdienen ihren eigenen Absatz, weil sie so häufig sind. Ein Electron-Helper namens Slack Helper (Renderer) öffnet eigentlich keine Sockets — das ist der Network-Service, meist Slack Helper (kein Suffix) oder Slack Helper (Plugin) je nach Electron-Version. Der Renderer spricht zum Network-Service über Chromiums Mojo-IPC-Bus.

Wenn Sie also nur Verkehr auf dem nackten Slack Helper sehen, ist das kein Bug — das ist die Architektur. Der Renderer macht die Anfrage, aber der Kernel sieht den Network-Service die I/O machen. Aus Nutzerperspektive sollten beide unter „Slack" zusammengefasst werden. Aus Debugging-Perspektive spart Ihnen das Wissen einen Nachmittag, wenn Sie sich fragen, warum der Renderer nicht aufleuchtet.

Dasselbe gilt für Chrome selbst: In aktuellen Chrome-Builds kommt fast aller Netzwerkverkehr von Google Chrome Helper (Plugin) oder dem Network-Service-Helper, nicht von den Pro-Tab-Renderern.

Warum Sie einfachen Summen nicht trauen können

Sobald Sie Hilfsprozesse verstehen, werden ein paar häufige Fragen leichter zu beantworten.

„Warum sieht meine Chrome-Nutzung niedrig aus?" Weil die Bytes über ein Dutzend Hilfsprozesse verteilt sind und Ihr Monitor sie nicht summiert. Jeder einzelne Helper sieht bescheiden aus.

„Warum tauchten plötzlich 200 MB unter einem Prozess auf, den ich nicht erkenne?" Wahrscheinlich ein Renderer für einen Video-Stream, ein XPC-Service, der Sync handhabt (CloudKit, iCloud, Dropbox), oder ein Systemdaemon, der Hintergrundarbeit macht. Schauen Sie auf den Executable-Pfad, nicht nur den Namen.

„Warum erscheint dieselbe App unter zwei verschiedenen Namen über Reboots hinweg?" Manche Hilfsprozesse enthalten eine Versionsnummer oder eine UUID im Prozessnamen. Die meisten Monitore strippen sie, aber nicht alle.

Folding in der Praxis — und wann es rückgängig zu machen

Ein Monitor, der Hilfsprozesse zusammenfasst, zeigt Ihnen etwas wie:

Google Chrome    412 MB ↓   18 MB ↑
Slack             89 MB ↓    4 MB ↑
Spotify           62 MB ↓  120 KB ↑
Dropbox           34 MB ↓   12 MB ↑

…statt:

Google Chrome Helper (Renderer)   38 MB ↓
Google Chrome Helper (GPU)         2 KB ↓
Google Chrome Helper (Plugin)    220 MB ↓
Google Chrome Helper             140 MB ↓
Google Chrome Helper (Renderer)   12 MB ↓
Slack Helper (Renderer)           41 MB ↓
Slack Helper                      48 MB ↓
... (geht für 30 weitere Zeilen)

Das erste ist, was Sie tatsächlich wollen. ova macht dieses Folding automatisch — es gruppiert jede Helper-PID unter dem Eltern-Bundle, sodass Sie „Slack" lesen statt sieben Helper-Zeilen.

Hilfsprozess-Zusammenfassung
ova gruppiert jede Helper-PID unter ihrer übergeordneten App, sodass Sie „Slack" lesen statt sieben Helper-Zeilen. Chrome, Slack, Discord, Telegram, VS Code, Figma — alles automatisch konsolidiert.

Wann Sie tatsächlich Hilfsprozesse sehen wollen

Es gibt einen Fall, in dem Folding stört: Debugging einer App, die sich daneben benimmt. Wenn Sie ein Entwickler sind und herausfinden wollen, welcher Chromium-Prozess Sockets leakt oder ob Ihr Renderer den Network-Service umgeht, wollen Sie die rohe Sicht.

Ein nützlicher Monitor lässt Sie in die zusammengefasste Zeile klicken und die zugrundeliegenden Hilfsprozesse sehen — Bytes pro Helper, aktuelle PID, voller Executable-Pfad. So ist die Standard-Sicht sauber, aber das Detail ist einen Tipp entfernt.

Das ist auch nützlich für Crash-Diagnose: Ein Helper, der alle 30 Sekunden neu startet und TLS-Sitzungen neu etabliert, kann überraschenden Hintergrundverkehr ansammeln, und es ist nur sichtbar, wenn Sie Helper-Ebenen-Historie sehen können.

Durchgang: ein Slack-Mysterium untersuchen

Angenommen, Slack zeigt heute 600 MB heruntergeladen und Sie haben keine Videos angeschaut. Hier ist die Reihenfolge, in der ich prüfen würde.

  1. Tageszeit-Muster prüfen. Eine Spitze um 9 Uhr ist wahrscheinlich der morgendliche Aufhol-Sync. Eine flache 24-Stunden-Kurve ist interessanter.
  2. Helper-Aufschlüsselung prüfen. Wenn 90 % in Slack Helper (Plugin) (dem Network-Service) sind, ist das „echter" App-Verkehr. Wenn es seltsam über Renderer aufgeteilt ist, könnten Sie einen geleakten Tab offen haben.
  3. Workspace-Anzahl prüfen. Jeder Slack-Workspace fügt einen persistenten WebSocket und seinen eigenen Avatar-/Datei-Cache hinzu. Drei Workspaces sind grob 3-mal der Idle-Verkehr von einem.
  4. Screen-Share- oder Huddle-Historie prüfen. Huddles nutzen WebRTC und fressen 1–3 MB/s, während aktiv.

Sie brauchen für nichts davon einen Paket-Capture. Sie brauchen einen Pro-App-Monitor, der Hilfsprozesse zusammenfasst und eine Stunde Historie hält.

Fazit

Hilfsprozesse sind keine Eigenheit, die zu umgehen ist — sie sind, wie moderne macOS-Apps sicher und stabil bleiben. Die Kosten sind, dass die Sicht des Kernels auf „wer hat das Netzwerk genutzt" wie eine kryptische flache Liste liest, und deshalb stolpert die Bandbreitenbuchhaltung von Mac-Hilfsprozessen jedes Allzweck-Tool. Jeder anständige Bandbreitenmonitor auf macOS muss Helper-Folding machen, und jeder, der das nicht tut, lässt Sie für den Rest Ihres Lebens Zeilen mental aufsummieren.

Wenn Ihr aktuelles Tool Ihnen rohe Helper-Zeilen zeigt und Sie satt haben, „Google Chrome Helper (Renderer)" zum tausendsten Mal zu lesen, installieren Sie ova — es sitzt in der Menüleiste mit etwa 3 MB, samplet mit grob 1 Hz und fasst Hilfsprozesse automatisch zusammen. Alle Daten bleiben auf Ihrem Mac. macOS 14 und neuer, Apple Silicon und Intel.