- Das Problem. Auf einem Entwickler-Mac lagen 30,18 GB doppelt. Das meiste davon steckte in den Containern anderer Apps und in Quellcode-Checkouts, wo das Löschen einer Kopie nicht sicher ist.
- Was wir herausgefunden haben. Ein Tool, das Speicherplatz durch Löschen freigibt, könnte davon ehrlicherweise etwa 3 % anbieten. APFS kann zwei identische Dateien ihre Blöcke teilen lassen: Beide bleiben erhalten, und der Platz kommt zurück.
- Was wir gebaut haben. Einen Scan, der den Speicher der Kopien im gesamten Benutzerordner teilt. Der erste Durchgang holte in 28 Sekunden 17,21 GB aus 8.414 Kopien zurück, und die Dateien bestanden danach jede Prüfung.
Wer doppelte Dateien findet, weiß noch nicht, welche Kopie weg kann. Ein Projekt braucht eine Datei womöglich genau an ihrem jetzigen Pfad, auch wenn dieselben Bytes anderswo liegen. Wir haben auf einem Mac 30,18 GB doppelt belegten Speicher gemessen und dann getestet, wann APFS Speicherplatz zurückgewinnen kann, ohne dass eine der beiden Dateien verschwindet. Wie viel dein Mac zurückbekommt, hängt von seinen Dateien ab und davon, welche Blöcke sie sich bereits teilen.
Wir haben auf einem Entwickler-Mac den gesamten Benutzerordner erfasst, um herauszufinden, was ihn füllt: 523.217 Dateien, gruppiert nach dem Platz, den sie tatsächlich belegen, gehasht, wo zwei Größen übereinstimmten, und Byte für Byte verglichen. Jedes Paar, das sich seine Blöcke auf der Festplatte schon teilt, haben wir aussortiert. Übrig blieben 30,18 GB, die der Mac doppelt speichert, verteilt auf 44.830 Gruppen.
Wir hätten hier aufhören und 30 GB auf eine Seite schreiben können. Was das Produkt verändert hat, war ein zweiter Blick auf dieselbe Bestandsaufnahme.
Zuerst die Bytes zählen, die es wirklich gibt
Auf einem aktuellen Mac ist die naheliegende Art zu zählen falsch, und zwar genau in die Richtung, die ein Speichertool gut aussehen lässt.
Die Größe einer Datei und der Platz, den sie belegt, sind zwei verschiedene Zahlen. Dieser Benutzerordner kommt auf 670,0 GB nach Dateigröße und 225,5 GB nach tatsächlich belegtem Speicher. Den größten Teil der Differenz machen 14.759 Dateien aus, die iCloud und andere Sync-Clients als Platzhalter führen: Sie haben einen Namen, ein Symbol und eine Größe, aber keine Bytes dahinter. Ein Tool, das Größen addiert, verspricht dir Hunderte Gigabyte, die es nicht gibt, und wenn du einen Platzhalter löschst, verlierst du deine einzige Kopie, ohne dass irgendetwas frei wird.
Deshalb steht jede Zahl in diesem Beitrag für belegte Bytes. Die Summen fallen kleiner aus, und du kannst sie mit deinem eigenen freien Speicherplatz abgleichen.
Zwei Arten, 30 GB zu lesen
Die erste Lesart fragt, was die Kopien sind. Der größte Block sind 13,06 GB KI-Modellgewichte, und eine 2,9 GB große Modelldatei lag an vier Stellen gleichzeitig: im Container einer App, in einer Test-Fixture, in einem Backup und in einem Support-Ordner. Danach folgen andere App-Daten, Build-Artefakte und schließlich Medien und Dokumente.
Die zweite Lesart fragt, wo sie liegen, und sie hat alles entschieden. 13,51 GB liegen in den Containern anderer Apps. 12,69 GB liegen in Quellcode-Checkouts. Weniger als ein Gigabyte liegt in Ordnern, in denen ein Aufräum-Tool ruhig vorschlagen darf, etwas zu löschen.
Ein Tool, das Speicherplatz freigibt, indem es Dateien entfernt, kann ehrlicherweise etwa 3 % dessen anbieten, was es gerade gefunden hat. Niemand will ein Aufräum-Tool, das im Container einer anderen App etwas zum Löschen vorschlägt oder in einem Quellcodebaum, an dem man noch arbeitet. Wir hätten einen Scanner ausliefern können, der 30 GB meldet und bei 1 GB tatsächlich etwas tut. Viele Tools machen es so.
Das Verb bestimmt die Reichweite
APFS kann zwei Dateien dieselben Blöcke teilen lassen. Der Aufruf heißt clonefile, der Finder nutzt ihn, wenn du eine Datei duplizierst, und er kostet weder Zeit noch zusätzlichen Platz. Beide Dateien bleiben, jede mit eigenem Namen, Ordner, Zugriffsrechten, Zeitstempeln und Inhalt. Geteilt wird nur der Speicher darunter.
Bei einer 200 MB großen Datei sehen die Zahlen so aus:
Der Platz war in dem Moment zurück, in dem die beiden anfingen zu teilen, und keine der Dateien hat etwas davon gemerkt.
Weil dieses Verb kein Risiko birgt, kann die Reichweite der gesamte Benutzerordner sein statt der paar Ordner, in denen sich ein Löschvorschlag vertreten lässt. Das Netz wird dadurch etwa dreißigmal weiter als das eines Duplikat-Finders, und der einzige Grund ist, dass das Verb nicht mehr löscht.
Eine Regel gilt durchgehend: Der Hash entscheidet nie über einen Schreibvorgang. Er grenzt nur die Kandidaten ein. Bevor irgendetwas geschrieben wird, werden die beiden Dateien Byte für Byte verglichen, damit eine Hash-Kollision niemanden Daten kosten kann.
Ein Scan des gesamten Benutzerordners mit 870.229 Dateien dauert beim ersten Mal 7,3 Sekunden und danach 5,4; in der ersten Version waren es noch 59,8. Deshalb kann er bei jedem Klick laufen statt nach Zeitplan.
Eine Zusage, die du prüfen kannst
Speichertools stecken voller Zahlen, die niemand nachprüfen kann. Diese hier hat einen Beleg, und wir haben dafür gesorgt, dass er sich auf drei voneinander unabhängigen Wegen prüfen lässt.
Die Zusage ist die Summe der Zeilen vor dem Durchgang. Der Beleg wird danach gemessen, indem wir die exklusiv belegten Bytes jeder ersetzten Datei neu einlesen. df ist die Buchführung des Volumes selbst und weiß von alldem nichts. Wenn die drei nicht übereinstimmen, war die Zusage falsch, und das finden wir lieber hier heraus, als dass es jemand auf der eigenen Festplatte merkt.
Danach haben wir die Dateien selbst geprüft, und zwar anhand von Aufzeichnungen, die es schon vor dem Durchgang gab und die wir nie schreiben:
- 3.478 von Git verfolgte Kopien ergeben weiterhin den Hash des Blobs, den Git gespeichert hat. Keine einzige weicht ab.
- 1.877 PNGs bestehen ihre internen Chunk-Prüfsummen, 77 Disk-Images ihre eigene Data-Fork-Prüfsumme, 11 SQLite-Datenbanken eine Integritätsprüfung, und jeder ZIP- und gzip-Eintrag besteht seine CRC-Prüfung.
- 164 Mach-O-Signaturen sind gültig, 54 signierte App-Bundles behalten ihr
codesign-Ergebnis und ihren Code-Directory-Hash, und 20 Debug-Symbol-Bundles behalten ihre UUIDs. - Zwei Kopien einer notarisierten App bestehen Gatekeeper weiterhin mit demselben Ergebnis wie vorher.
Eine Datei, die ihre Blöcke teilt, ist immer noch dieselbe Datei. Dass wir das sagen können, verdanken wir diesen Prüfungen.
Zwei Fehler im ersten echten Durchgang
Der Durchgang hat zwei Dinge verändert, die er nicht hätte verändern dürfen: das Finder-Datum „Hinzugefügt am“ und, bei 301 der 8.414 Kopien im ersten Durchgang über den gesamten Benutzerordner, die Angabe, mit welcher App die Datei heruntergeladen wurde. Mint vergleicht die Attribute jeder Datei inzwischen vorher und nachher, sodass sich an der Datei nichts ändert außer dem Platz, den sie belegt.
Was wir gemessen und nicht gebaut haben
macOS kennt ein Flag für transparente Komprimierung, und auf diesem Mac war die Rechnung verlockend. Nach Stichproben über die ganze Festplatte hätte Komprimierung 57,5 GB zurückgebracht, mehr als das Teilen von Blöcken, und jede Datei wäre voll nutzbar geblieben. Apple setzt sie für den Großteil des Systems ein.
Wenn du Coding-Agenten nutzt, ist das dein Mac
Die 13,06 GB doppelter Modellgewichte sind typisch für einen Rechner, auf dem Agenten laufen. Ein Mac ohne Agenten sieht selten so aus.
Agenten kopieren Dinge absichtlich. Ein Modell wird einmal für die App geladen und ein zweites Mal in ihren Sandbox-Container. Jeder Worktree, den ein Agent anlegt, bringt seine eigenen Build-Artefakte mit. Eine Test-Fixture enthält eine Kopie der Datei, gegen die sie testet. Nichts davon ist ein Fehler, und nichts davon willst du von Hand löschen, weil du nicht immer erkennen kannst, von welcher Kopie etwas abhängt.
Blöcke zu teilen passt gut zu diesem Fall. Du musst nicht wissen, auf welche Kopie es ankommt, weil alle weiter funktionieren, und du musst weder den Agenten beenden noch irgendetwas entscheiden. Der erste Durchgang über den gesamten Benutzerordner: 3.262 Gruppen, 8.414 Kopien, 28 Sekunden, nichts abgelehnt, 17,21 GB zurück. Ein neuer Scan fand danach noch 37 MB, die von gerade laufenden Apps offen gehalten wurden.
Was wir daraus mitnehmen
Die Gesamtsumme war nie die nützliche Zahl. Nützlich war die Aufteilung nach Ort, denn sie zeigte, dass das, was ein Scanner melden kann, und das, was ein Aufräum-Tool tatsächlich angehen kann, zwei verschiedene Zahlen sind, die um den Faktor dreißig auseinanderliegen. Alles Weitere ergab sich daraus, dass wir das Verb geändert haben, statt um weitergehende Berechtigungen zu bitten.
Ein Tool, das Speicherplatz verspricht, sollte ihn hinterher auch nachweisen können. Bei einem Durchgang, der 8.414 echte Dateien eines Menschen berührt hat, stimmten Zusage, Beleg und Volume aufs Byte überein.
Entscheide, ob Kopien bleiben sollen
Mit der Anleitung zu doppelten Dateien unterscheidest du Dateien, die weg können, von Kopien, die an ihrem Ort weiter funktionieren sollen. Wenn die Systemdaten sehr groß sind, beginne mit der Diagnose der Systemdaten: Die Summe der Kategorie allein sagt dir nicht, was du löschen kannst.