O Que É um OOM Kill em CI? Explicação
Um OOM kill é o sistema operacional encerrando à força um processo porque a máquina ficou sem memória, usando SIGKILL, que não pode ser capturado nem limpo.
Em um runner de CI com pouca memória, um processo de build ou de teste que aloca mais do que está disponível não recebe um erro educado. O out-of-memory killer do kernel entra em ação e encerra o processo mais pesado para recuperar memória. O resultado é uma falha abrupta e sem traceback que confunde muitos times na primeira vez.
Como o OOM killer funciona
Quando o sistema (ou um limite de memória de cgroup) fica sem memória, o kernel precisa liberar alguma imediatamente. Ele seleciona um processo, geralmente o maior, e envia SIGKILL (sinal 9). O SIGKILL não pode ser capturado, bloqueado nem tratado, então o processo morre instantaneamente sem chance de logar ou limpar.
Como ele aparece
Você normalmente vê a palavra nua "Killed", um exit code de 137 (128 + 9) e nenhum stack trace, porque o processo nunca chegou a produzir um. Em um container, você também pode ver um status "OOMKilled". A ausência de um erro normal é, em si, a pista.
Por que é comum em CI
- Runners têm memória fixa, muitas vezes modesta; builds têm picos bem acima do uso médio.
- Workers de teste paralelos cada um mantém uma cópia de memória e multiplicam o pico de uso.
- Runtimes de linguagem (JVM, Node) reservam heaps grandes que podem exceder o limite.
- Um limite de memória de container pode ser menor que o do host, então o limite é atingido primeiro.
Transitório ou determinístico?
Um OOM kill pode ser qualquer um dos dois. Se seu build genuinamente precisa de mais memória do que o runner tem, ele é determinístico e você precisa de um runner maior ou de um pico de uso menor. Mas se o runner estava apenas momentaneamente carregado ou o pico foi marginal, um retry em um runner novo muitas vezes passa, o que o torna transitório.
A perspectiva da Latchkey
Os managed runners com autocorreção da Latchkey detectam out-of-memory kills como uma classe de falha mecânica e automaticamente fazem retry do job afetado, de modo que um pico de memória isolado e marginal não faça seu build falhar. Builds que são genuinamente grandes demais para seu runner ainda aparecem, para que você possa dimensioná-los corretamente.
Principais conclusões
- Um OOM kill é o kernel encerrando um processo via SIGKILL não capturável.
- Ele aparece como "Killed", exit code 137 e nenhum stack trace.
- Workers paralelos e heaps grandes de runtime o tornam comum em CI.
- Um pico marginal é transitório e passível de retry; uma escassez genuína exige um runner maior.