Files
philips-tv-speicher-voll/diagnostics/storage-analysis.md

13 KiB
Raw Blame History

Speicheranalyse – /data und adoptierter Speicher

Stand: 2026-08-25, vertieft bis 14:20 Uhr. Die TV-Abfragen waren bis auf die vom Auftrag ausdrücklich verlangte Android-Diagnose dumpsys diskstats lesend. Dieser Dienst meldet selbst einen 512-Byte-Latenztest ([512B Data Write]); er wird deshalb nicht nochmals verwendet.

Kurzfazit

Die interne /data-Belegung ist jetzt zu rund 75,7 % konkret erklärt. Der größte Einzelverursacher ist eine Philips-EPG-Datenbank mit 1,62 GiB. Daneben ist eine Philips-WorkManager-Datenbank mit 218,8 MiB extrem auffällig. Aktualisierte vorinstallierte Apps samt direkt messbaren Basiskompilaten beanspruchen mindestens weitere 912,6 MiB. Ob und wie viel der beiden SQLite-Hauptdateien intern frei ist, bleibt ohne freelist_count unbekannt.

Das 112-GiB-adoptierte Volume ist korrekt als privater und primärer Speicher eingebunden, bleibt aber fast leer. Es kann diese Hauptverursacher nicht automatisch aufnehmen: Sie gehören zu Systempaketen, und Android verbietet das Verschieben von System-Apps. Auch alle 18 Pakete unter /data/app sind trotz ihres Pfades keine normalen Drittanbieter-Apps, sondern aktualisierte System-Apps.

Objektive Lage

Bereich Größe/Belegung Bewertung
/data gesamt 4.970,6 MiB kleines internes Dateisystem
/data belegt zuletzt 3.831.944 KiB = 3.742,1 MiB (78 %) real belegt; laufende TV-Daten schwanken
/data verfügbar zuletzt 1.136.840 KiB = 1.110,2 MiB Android NORMAL
Abstand zur Philips-Schwelle zuletzt 88.264 KiB = 86,2 MiB sehr geringe Schwankungsreserve
adoptiert, privat 112,3 GiB, nur 1,36 MiB belegt technisch intakt, praktisch leer
öffentliches USB-Volume 58,2 GiB, 42,2 GiB frei unkritisch

Inodes sind nicht knapp: /data nutzt 7 % seiner Inodes. Der Android- DeviceStorageMonitor meldet NORMAL; dessen Low-Schwelle liegt bei rund 249 MiB. Die Warnung entsteht weiterhin an Philips' separater 1-GiB-Schwelle.

Konkrete Belegungsverursacher

Struktur Messwert Anteil an aktueller /data-Belegung Evidenz
org.droidtv.channels/.../EpgDatabase.db 1.661,352 MiB = 1,622 GiB 44,5 % dumpsys dbinfo/meminfo
org.droidtv.gel/.../androidx.work.workdb 218,8 MiB 5,9 % dumpsys dbinfo
alle weiteren von dbinfo gelisteten DB-Dateien/Sidecars 29,1 MiB zusätzlich 0,8 % dienstvermittelte Dateiliste, dedupliziert
18 aktualisierte System-Apps: sichtbarer Code 686,2 MiB 18,4 % du bekannte Codepfade
deren statbare Basis-ODEX/VDEX 226,4 MiB 6,1 % stat exakte OAT-Dateien
/data/anr und kleine zusätzliche Bugreport-Artefakte 8,7 MiB 0,2 % direkt/Bugreport
konservativ konkret zugeordnet 2.830,5 MiB = 2,764 GiB 75,7 % synchronisierte Abschlussbilanz
verbleibend, nicht einzeln messbar ca. 905–912 MiB = 0,88–0,89 GiB ca. 24,3 % zeitabhängige Differenz

Der Rest umfasst unter anderem weitere Split-OAT-Dateien, private Nicht-DB- Appdaten, Dalvik-Cache, /data/system, /data/misc und Dateisystem-Overhead. Wegen DAC und SELinux ist eine vollständige du-Aufteilung auf diesem Produktions-Build nicht möglich. Die genannten 75,7 % sind deshalb keine Schätzung nach Kategorien, sondern eine konservative, deduplizierte Summe dienstvermittelter oder direkt statbarer Werte. Der spätere df-Stand wich um rund 6 MiB ab; deshalb wird das Ergebnis sinnvoll als 75–76 % angegeben.

1. Philips EPG-Datenbank

Pfad:

/data/user/0/org.droidtv.channels/databases/EpgDatabase.db

Androids Datenbankdienst meldet 1.742.053.376 Byte; das Rollback-Journal ist 0 Byte, und es existieren in der Momentaufnahme weder WAL noch SHM. dumpsys meminfo 7267 belegt pgsz=4 KiB und dbsz=1.701.224 KiB. Damit sind page_size=4096 Byte und page_count=425.306 exakt bewiesen (425.306 × 4096 = 1.742.053.376). Eine physische Blockzählung wurde der Shell verweigert; die fast vollständige Übereinstimmung mit df macht eine weitgehend reale Blockbelegung sehr wahrscheinlich, Sparse-Anteile sind aber nicht separat ausgeschlossen.

Der ContentProvider erlaubt eine weitere, rein lesende Prüfung:

Tabelle aktuelle Zeilen beobachtete AUTOINCREMENT-IDs
indextable 358 1.267.806–1.268.163
nowtable 195 4.431.681–4.451.328
nexttable 162 4.026.589–4.027.685
nownexttable 358 korrespondierende aktuelle IDs
fastipnownexttable 0 –

Damit sind millionenfache historische Inserts bei wenigen aktuellen Index-/Now-/Next-Zeilen direkt nachgewiesen. Die statische DEX-Analyse korrigiert jedoch einen früheren Schluss: deleteStaleDataRunnable.run() berechnet nur Grenzwerte und protokolliert „Deleting stale data“, führt aber keine Löschung aus. Zusätzlich werden 1800 und 604800 direkt von currentTimeMillis() subtrahiert; die protokollierte 1,8-Sekunden-Differenz bestätigt den Einheitenfehler. Die echten Zeit-Löschmethoden sind in den vier DEX-Dateien nicht an diesen Pfad verdrahtet.

Die Philips-rebuilddb-Pfade sind ebenfalls kein physischer Rebuild: dropTables() führt SQLiteDatabase.delete() auf Tabellen aus, ersetzt die Datei aber nicht und ruft kein VACUUM auf. Eine explizite PRAGMA auto_vacuum-Anweisung fehlt im APK. Zugleich baut AOSP seine Plattform- SQLite-Bibliothek langjährig mit SQLITE_DEFAULT_AUTOVACUUM=1 (FULL). Da dieses Gerät /system/lib/libsqlite.so Version 3.32.2 verwendet, ist FULL für eine normal durch SQLiteOpenHelper neu angelegte Datenbank eine starke Inferenz, aber kein gemessener Headerwert dieses Philips-Vendor-Builds.

Eine lesende Vollabfrage von scheduletable war nach 120 Sekunden noch nicht beendet und wurde abgebrochen. Das beweist keine Zeilenzahl, zeigt aber, dass aktive Schedule-Daten keinesfalls als vernachlässigbar angenommen werden dürfen. Deshalb gilt nun streng:

  • freelist_count: NICHT VERIFIZIERBAR;
  • intern freier Platz: NICHT BERECHENBAR (freelist_count × 4096);
  • auto_vacuum: NICHT direkt verifiziert, FULL ist AOSP-basiert plausibel bis sehr wahrscheinlich;
  • „fast die gesamte Datei ist leer“: nicht belegt.

SQLite dokumentiert sowohl das Freelist-Verhalten als auch, dass VACUUM die DB in eine temporäre Datei kopiert und bis zum Zweifachen der Ursprungsgröße an zusätzlichem freien Platz benötigen kann. Bei nur rund 1,1 GiB frei ist das für eine 1,62-GiB-Datei nicht sicher durchführbar und bleibt ausdrücklich verboten. Quellen: SQLite VACUUM, PRAGMA auto_vacuum und AOSP SQLite-Buildoptionen.

2. Philips GEL-WorkManager-Datenbank

Pfad:

/data/user/0/org.droidtv.gel/no_backup/androidx.work.workdb

Die Datei hat 229.453.824 Byte. Android meldet page_size=4096 Byte und je nach Momentaufnahme page_count=56.019–56.020. Dazu kommen nur 524.288 Byte WAL und 32.768 Byte SHM; der Ausreißer steckt also in der Hauptdatei und nicht in einem außer Kontrolle geratenen WAL. Übliche WorkManager-Dateien auf demselben Gerät liegen bei rund 98–106 KiB; GEL ist ungefähr 2.155-mal größer. dbinfo zeigt aktuelle Inserts in WorkSpec, Dependency, WorkTag und WorkName.

Die statische APK-Analyse belegt:

  • GatheringService baut für jeden Start einen OneTimeWorkRequest;
  • der eindeutige Name lautet GEL_WORK;
  • der optimierte Bytecode verwendet die Konfliktpolitik APPEND_OR_REPLACE (unboxed enum value 4);
  • der Dienst läuft im langlebigen Systemprozess org.droidtv.candeebug.

Android beschreibt, dass APPEND_OR_REPLACE neue Arbeit an die Blätter einer vorhandenen Kette anhängt. Das stimmt mit den beobachteten Dependency-Insertionen überein. Quelle: Android ExistingWorkPolicy.

Bewertung: Eine über Jahre gewachsene WorkManager-Kette oder daraus entstandene freie SQLite-Seiten ist sehr wahrscheinlich. Ohne privilegierten SQL-Lesezugriff sind Tabellenzählung und Freelist auch hier nicht endgültig trennbar.

3. Aktualisierte System-Apps

pm list packages -3 ist leer. Dennoch liegen 18 aktive Codepfade unter /data/app; bei allen meldet PackageManager die Flags SYSTEM und UPDATED_SYSTEM_APP sowie eine ältere, unveränderliche Ursprungskopie unter /system/product oder /vendor.

Die sichtbaren APK-/Split-/DM-Anteile summieren sich auf 686,2 MiB. Durch gezieltes stat bekannter oat/arm/base.odex- und base.vdex-Pfade kommen mindestens 226,4 MiB hinzu. Größte Mindestbelegungen:

Paket mindestens
Google Play Services 243,0 MiB
Netflix 105,4 MiB
Google Text-to-Speech 96,6 MiB
Android WebView 93,3 MiB
Play Store 63,0 MiB
YouTube 52,1 MiB

Split-Kompilate und private Daten fehlen in diesen Mindestwerten. Die Updates belegen zusätzlich Platz, während ihre Werksversionen im schreibgeschützten Systemimage unverändert vorhanden bleiben.

Warum der adoptierte Speicher leer bleibt

Die Konfiguration ist objektiv korrekt:

  • privates ext4-Volume 0ca93141-... ist MOUNTED;
  • das zugehörige emulierte Volume trägt PRIMARY|VISIBLE;
  • sm get-primary-storage-uuid liefert dessen UUID;
  • /storage/emulated/0 zeigt bereits auf dessen media-Bereich;
  • Installationsmodus ist 0[auto].

Androids AOSP-Dokumentation erklärt, dass adoptierter Speicher Apps und private Daten nur für unterstützte Apps aufnehmen kann und die Migration primär den gemeinsamen /sdcard-Inhalt betrifft. Androids PackageManager lehnt das Verschieben von Systempaketen ausdrücklich mit MOVE_FAILED_SYSTEM_PACKAGE ab. Quellen: AOSP Adoptable Storage und AOSP Android-12 PackageManager-Logik.

Genau diese Einschränkung trifft hier zu: Es gibt keine Drittanbieterpakete, alle 18 aktualisierten Pakete sind weiterhin System-Apps, und auch org.droidtv.channels sowie org.droidtv.gel sind Systempakete mit UID 1000. Das adoptierte Volume dient daher aktuell fast nur als primärer gemeinsamer Medienspeicher; dort liegen lediglich etwa 1,2 MiB.

Separate Philips-Partition user_setting

Eine beim Aufwachen sichtbare TvProvider-Zeile meldete 762.183.680 Byte verfügbar. Das ist kein neuer /data-Messwert. Die Mounttabelle belegt:

/dev/block/mmcblk0p52 on /data/vendor/user_setting type ext4

Die rekonstruierte Kernel-Partitionsdefinition weist mmcblk0p52 1000 MiB zu. Statische Analyse von TvProvider.apk zeigt, dass checkDBSizeOverThreshold() für exakt /data/vendor/user_setting ein StatFs erzeugt und blockSize * availableBlocks protokolliert. Der Provider setzt seine interne Stufe 2 unter 10 % frei und Stufe 1 unter totalBytes / 7,69, also rund 13,0039 % frei.

762.183.680 Byte entsprechen 726,875 MiB und rund 72,6875 % der rohen 1000-MiB-Partition. Weil die StatFs-Gesamtgröße den ext4-Overhead bereits abzieht, liegt der wirkliche freie Prozentsatz des Dateisystems eher noch etwas höher. Im vorherigen Bugreport blieb der Wert über mindestens 90 Minuten nahezu konstant; USER_SETTING_10_FREE- oder Insert-Blockiermeldungen wurden nicht gefunden. Die Partition enthält unter anderem rw/tv.db und list.db, ist derzeit aber klar nicht knapp.

Direktes df, Listing und das Lesen der p52-Sysfs-Größenknoten wurden der ADB-Shell verweigert. Diese Grenze wurde akzeptiert. Der Befund beruht daher auf der direkt sichtbaren Mountzuordnung, der Commandline-Größe, dem laufenden UID-1000-StatFs-Log und der lokalen DEX-Analyse.

Schlussfolgerung zur Warnung

Die Meldung ist kein bloßer falscher Zähler, aber auch kein Android-Low-Storage- Alarm. /data hat real nur rund 1,08–1,11 GiB verfügbar und schwankt knapp um Philips' eigene 1-GiB-Warnschwelle. Die beiden ungewöhnlich großen Philips-Datenbanken belegen zusammen rund 1,84 GiB und sind die wichtigsten konkreten Ursachen für diesen knappen Zustand. Die EPG-Datenbank allein ist größer als der gesamte aktuell freie Platz. Ihre genaue reclaimbare Teilmenge ist noch unbekannt; Ursache und Rückgewinn dürfen nicht gleichgesetzt werden.

Der eMMC-Wert 0x0a 0x0a verändert nicht die Belegung, sorgt aber dafür, dass Philips eine Unterschreitung der 1-GiB-Schwelle als MEMORY_CRITICAL darstellt. Damit sind Belegungsursache und Warnschärfe getrennt erklärt.

Rohdaten

  • raw/storage/filesystem-overview.txt
  • raw/storage/data-access-map.txt
  • raw/storage/updated-system-apps.tsv
  • raw/storage/adopted-storage.txt
  • raw/storage/database-outliers.txt
  • raw/storage/epg-content-evidence.txt
  • raw/storage/final-validation.txt
  • raw/storage/channels.apk
  • raw/storage/gel.apk