Daemon für den Prozessspeicherschutz

Android 17 und höher unterstützt den PMGD-Daemon (Process Memory Guardian), der die Systemintegrität und die Nutzerfreundlichkeit schützt, indem er die Arbeitsspeichernutzung proaktiv pro Prozess verwaltet. Der Daemon verbessert die allgemeine Gerätestabilität, indem er Speicherlimits für bestimmte Zielprozesse erzwingt und dafür sorgt, dass isolierte Speicherlecks oder ‑spitzen nicht zu einer systemweiten Leistungsbeeinträchtigung führen.

Herkömmliche globale Low-Memory-Killer werden nur aktiv, wenn das gesamte System unter Druck steht. PMGD verfolgt einen detaillierten Ansatz. Der Daemon erreicht dies, indem er die Control Group v2-Speicher-Werte für seine Zielprozesse überwacht. Wenn ein Zielprozess seine konfigurierten Speicherlimits überschreitet, werden Limitüberschreitungen von pmgd behandelt, indem Statsd-Speicher-Atome protokolliert werden, bevor der Prozess beendet wird.

Funktionsweise

Der Daemon verwendet inotify, um auf Ereignisse mit hohem Speicherdruck zu warten (insbesondere Aktivitäten mit hohem Speicherverbrauch mit memory.events). Wenn ein überwachter Prozess ein Speicherereignis auslöst, führt pmgd die folgenden Aktionen aus:

  1. Anonymer Arbeitsspeichercheck:Hier wird der anonyme Arbeitsspeicher des Prozesses ausgewertet. Wenn der Wert den konfigurierten anon_limit_in_mb überschreitet, beendet pmgd den Prozess sofort.
  2. Wartezeit für die Rückforderung:Wenn der anonyme Speicher unter dem angegebenen Limit für anonymen Speicher liegt, wartet pmgd auf eine Kulanzfrist für die Systemrückforderung (reclaim_wait_time_secs).
  3. Arbeitsspeicherbewertung nach dem Zurückfordern:Wenn memory.current des Zielprozesses nach der Kulanzfrist weiterhin größer oder gleich memory.high ist oder der anonyme Arbeitsspeicher anon_limit_in_mb überschreitet, beendet pmgd den Prozess sofort.

Dies geschieht kontinuierlich, bis der Prozess beendet wird oder die Arbeitsspeichernutzung des Prozesses durch die Rückforderung unter die angegebenen Speicherlimits sinkt.

Funktionen für den Systemzustand

  • Ratenbegrenzung für Neustarts:Um Bootloops oder anhaltende Abstürze zu verhindern, verfolgt pmgd das Beenden von Prozessen in /data/misc/pmgd/history.json. Der Daemon beschränkt Prozesse auf einen einzigen von pmgd initiierten Kill pro Geräteneustart.

SELinux-Konfiguration

Die Möglichkeit von PMGD, Prozesse zu überwachen, wird durch die SELinux-Richtlinie eingeschränkt. Wenn Sie PMGD so konfigurieren, dass ein Prozess überwacht wird, dessen Domain laut Richtlinie nicht zulässig ist, z. B. ein anbieterspezifischer Systemprozess, kann PMGD ihn nicht überwachen. Möglicherweise sehen Sie SELinux-Verweigerungen in logcat.

Damit PMGD Prozesse in zusätzlichen Domains überwachen kann, müssen Sie die Berechtigungen von PMGD erweitern, indem Sie die gerätespezifische SELinux-Richtlinie für PMGD aktualisieren.

Hier sehen Sie eine device/<vendor>/<device>/sepolicy/pmgd.te-Beispieldatei, mit der der Zugriff auf eine neue Domain hinzugefügt wird:

# Allow pmgd to access vendor_system_apps
r_dir_file(pmgd, vendor_system_apps)

Weitere Informationen zum Schreiben gerätespezifischer Richtlinien finden Sie unter SELinux implementieren.

Vom Anbieter definierte Konfiguration

Die PMGD-Konfiguration wird vom Anbieter gesteuert und über eine erforderliche JSON-Datei /vendor/etc/pmgd/config.json konfiguriert. Hier werden die zu verfolgenden Prozesse, ihr konfiguriertes Arbeitsspeicherlimitprofil (mit cgroup-Aufgabenprofilen) und das harte anonyme Arbeitsspeicherlimit in Megabyte aufgeführt.

Felder für die Anbieterkonfiguration

Die bereitgestellte JSON-Konfiguration ist eine Liste von Prozessen und ihren Grenzwerten, die durch die folgenden Felder definiert werden:

Feld Typ Erforderlich Beschreibung Standard
target_cmd String Ja Der Befehlsname des zu überwachenden Zielprozesses, z. B. system_server.
uid Ganzzahl Nein Die Nutzer-ID (UID) des Prozesses. Wenn nichts angegeben ist, wird die Regel global auf alle Prozesse angewendet, die mit target_cmd übereinstimmen.pmgd
reclaim_wait_time_secs Ganzzahl Nein Die Kulanzzeit in Sekunden, die gewartet wird, bis das System Speicher zurückgewinnt, bevor das Speicherlimit noch einmal geprüft wird. 5
mem_limit_profile String Ja Der Name des Cgroup-Aufgabenprofils, mit dem „memory.high“ festgelegt wird. Damit wird das Prozessspeicherlimit festgelegt.
anon_limit_in_mb Ganzzahl Ja Das ultimative anonyme Arbeitsspeicherlimit in Megabyte. Wenn die Nutzung des anonymen Speichers diesen Wert überschreitet, beendet pmgd den Prozess sofort.
additional_task_profiles Liste mit Zeichenfolgen Nein Eine Liste aller zusätzlichen Aufgabenprofile, auf die pmgd angewendet wird, wenn die Überwachung beginnt. Leere Liste

Das Folgende ist ein Beispiel für die Konfiguration des Cgroup-Aufgabenprofils in vendor/etc/task_profiles.json:

{
  "Attributes": [
    ...
    {
      "Name": "MemHigh",
      "Controller": "memory",
      "File": "memory.high"
    }
  ],
  "Profiles": [
    {
      "Name": "SystemServerMemoryHighLimit",
      "Actions": [
        {
          "Name": "SetAttribute",
          "Params":
          {
            "Name": "MemHigh",
            "Value": "1080M"
          }
        }
      ]
    }
  ]
}

Das Folgende ist ein Beispiel für die Konfiguration von PMGD in vendor/etc/pmgd/config.json:

{
  "targets": [
    {
      "target_cmd": "system_server",
      "uid": 1000,
      "reclaim_wait_time_secs": 5,
      "mem_limit_profile": "SystemServerMemoryHighLimit",
      "anon_limit_in_mb": 300
    }
  ]
}