Das Symptom
Der Build läuft lokal durch, im CI stirbt er mit Exit-Code 137. Das ist kein Fehler im Code, sondern das Signal des Kernels: Der Prozess wurde beendet, weil ihm der Speicher ausging. Die naheliegende Reaktion — dem Runner mehr Arbeitsspeicher geben — verschiebt das Problem nur.
Nicht raten, messen
Statt am Speicherlimit zu drehen, lässt man die Laufzeit erzählen, wohin der Speicher fließt. Ein ausführliches Garbage-Collection-Log zeigt die Belegung über die Zeit: Wächst sie stetig und wird nie wieder freigegeben, ist es ein Leck; kommt sie in Sägezähnen zurück, ist es nur eine kurze Spitze.
Im konkreten Fall zeigte das Log:
- Die Belegung stieg monoton, GC-Pausen wurden immer länger.
- Kurz vor dem Abbruch hielt ein einziger Cache über ein Gigabyte — aufgebaut während des Builds, nie geleert.
- Der Compiler selbst blieb genügsam. Der Verdächtige war die Build-Logik drumherum.
Die Behebung
Der Cache bekam eine Obergrenze und wurde nach jedem Schritt freigegeben. Danach blieb die Belegung flach, die GC-Pausen kurz, der Build grün — ohne dem Runner ein Byte mehr Speicher zu geben.
Die Lehre
Out-of-Memory ist eine Aussage über Belegung, nicht über den offensichtlichsten Prozess. Das Speicher-Log zeigt den wahren Verursacher; das Limit anzuheben übertönt ihn nur, bis der Datensatz eine Spur größer wird.