Zygote-Prozesse

Der Zygote ist ein Prozess im Android-Betriebssystem, der als Stamm aller System- und App-Prozesse mit derselben Binärschnittstelle (Application Binary Interface, ABI) fungiert.

Auf modernen Geräten wie Google Pixel 7 und höher wird ein 64‑Bit-Zygote-Prozess verwendet. Außerdem gibt es den WebView-Zygote für das primäre ABI. Das ist ein spezieller Zygote, der Bibliotheken und Ressourcen für Prozesse enthält, in denen WebViews ausgeführt werden.

Das Zygote führt folgende Aufgaben aus:

  1. Der Init-Daemon startet den Zygote-Prozess, wenn das Android-Betriebssystem initialisiert wird. Bei einigen Systemen mit zwei Architekturen werden zwei Zygote-Prozesse (ein 64-Bit und ein 32-Bit) erstellt. Auf dieser Seite werden nur Systeme mit einer einzelnen Architektur behandelt.

  2. Der Zygote kann sofort Prozesse erzeugen, die als unspezialisierte App-Prozesse (USAP) bezeichnet werden, oder warten, bis Prozesse nach Bedarf von Anwendungen erzeugt werden. Die erste Option muss über eine Systemeigenschaft oder einen Android Debug Bridge-Befehl aktiviert werden. Weitere Informationen zum Konfigurieren von Zygote für die sofortige Erstellung von Prozessen finden Sie unter Pool ohne spezialisierte Anwendungsprozesse aktivieren .

    • Wenn der USAP-Pool auf Ihrem Gerät aktiviert ist:

      1. Der Systemserver verwendet einen Unix-Domain-Socket, um eine Verbindung zu einem verfügbaren USAP aus einem Pool herzustellen. Der Systemserver fordert an, dass die USAP für die Anwendungsnutzung vorkonfiguriert wird, indem die ID (PID), die Cgroup und andere Informationen des Prozesses geändert werden.
      2. Wenn die USAP die Vorkonfigurierung abgeschlossen hat, antwortet sie dem Systemserver mit der PID.
      3. Wenn eine App einen dieser USAPs belegt, ist die USAP nicht mehr Teil des Pools. Wenn der Pool einen oder weniger USAPs im Pool erreicht, füllt der Zygote den Pool mit neuen USAPs auf.
    • Wenn Ihr Zygote Prozesse mit Lazy Evaluation erstellt:

      1. Der Systemserver erhält den Befehl, dass eine App einen Prozess benötigt.
      2. Der Systemserver verwendet einen Unix-Domain-Socket, um einen Befehl an die entsprechende Zygote zu senden.
      3. Der Zygote teilt den Prozess und ändert die PID, die Cgroup und andere Informationen.
      4. Nach Abschluss des Vorgangs sendet der Prozess die PID an den Zygote zurück, der sie dann an den Systemserver weitergibt.

USAP-Pool aktivieren

So aktivieren Sie die Verwendung des USAP-Pools:

  • Legen Sie die Systemeigenschaft dalvik.vm.usap_pool_enabled in /build/make/target/product/runtime_libart.mk auf true fest.

  • Führen Sie den folgenden Befehl aus:

    adb shell am broadcast -a \"com.google.android.gms.phenotype.FLAG_OVERRIDE\" --es package \"com.google.android.platform.runtime_native\" --es user \"\*\" --esa flags \"usap_pool_enabled\" --esa values \"true\" --esa types \"string\" com.google.android.gms
    

Wenn diese Funktion aktiviert ist, verwaltet jedes Zygote einen Pool von gegabelten Prozessen, die die anwendungsunabhängigen Teile des Anwendungsstartprozesses ausführen.

Probleme mit Zygote beheben

Dieser Abschnitt enthält Lösungen für Probleme im Zusammenhang mit Zygote.

Der Zygote stürzt ab

Wenn Ihr Gerät nicht ordnungsgemäß neu startet und in Ihren Protokollen oder Absturzberichten Probleme mit dem Zygote angezeigt werden, liegt dies wahrscheinlich daran, dass Sie kürzlich eine Änderung vorgenommen haben, die eine Initiierung oder einen Absturz des Systemservers zur Folge hat. Wenn Sie den Code korrigieren, sollte das Problem behoben werden.

SELinux-Denials oder I/O-Fehler

Der Zygote achtet besonders auf die Dateideskriptorhygiene über Prozessgrenzen hinweg. Wenn Dateideskriptoren zum Zeitpunkt des Forks vorhanden sind, aber nicht in einer Zulassungsliste, verwenden wir einen dup-Systemaufruf an /dev/null, um zu verhindern, dass im Cache vorhandene Dateideskriptoren versehentlich zum Zugriff auf neu geöffnete Dateien verwendet werden.

Wenn Sie Framework-Änderungen vornehmen, bei denen versucht wird, Ressourcen in den Zygote zu laden, und Sie SELinux-Denials oder IO-Fehler erhalten, gehen Sie so vor:

  • Geben Sie bei unbenannten Dateideskriptoren die Dateideskriptoren in den fds_to_ignore-Vektor ein, wenn Restat aufgerufen wird.

  • Für benannte Dateideskriptoren:

    1. WORKING_DIRECTORY/frameworks/base/core/jni/fd_utils.cpp bearbeiten
    2. Fügen Sie den Pfad zur Zulassungsliste für geöffnete Dateien hinzu.