Sentry.Sources keeps the decoded source-code map on its heap after loading it into ETS

Aperta Adatta ai principianti
#1,259 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
76/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
elixir
Ambito
backend

Direzione di ricerca

Inizia leggendo Sentry.Sources.handle_continue/2, in particolare la clausola :load_source_code_map che decodifica la mappa inclusa e inserisce voci in ETS. Esamina i test del callback GenServer e verifica che il processo rilasci la mappa decodificata dopo il caricamento, mentre le voci ETS restano disponibili. L’issue non indica un file di test, quindi individua i test pertinenti nel repository.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Environment
  • sentry 13.4.2, Elixir 1.20.4 / OTP 29.1.1, enable_source_code_context: true
  • Release with a packaged source-code map (mix sentry.package_source_code)
What happens

Sentry.Sources.handle_continue(:load_source_code_map, state) decodes the whole map (:erlang.binary_to_term/1 on the packaged file), inserts each entry into the :sentry_source_code_map ETS table and returns {:noreply, state}. The process then receives no further messages, so it never triggers a garbage collection. The decoded term, which ETS has already copied, stays on the process heap for the life of the node.

On a ~6,400-module app this was about 57 MB per node, on top of the ~54 MB the ETS table needs:

pid = Process.whereis(Sentry.Sources)
Process.info(pid, :total_heap_size)   # ~7.1M words ≈ 57 MB
:erlang.garbage_collect(pid)
Process.info(pid, :total_heap_size)   # near zero

This matters on small machines: on a 1 GB container, this one process held ~6% of RAM for nothing.

Suggested fix

Shrink the heap once the load is done, for example:

{:noreply, state, :hibernate}

or an explicit :erlang.garbage_collect() before returning from handle_continue/2. :hibernate is enough because the process is idle afterwards. Decoding the map outside the GenServer (in a short-lived task) would also avoid it.

Workaround

After the application starts, we wait for the load to finish with :sys.get_state(Sentry.Sources) and then call :erlang.garbage_collect/1 on the process.

Lingua principale
Elixir
Stelle
692
Fork
219
Merge medio
2g 19h
PR unite (30g)
16

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di getsentry/sentry-elixir

Tutte le issue di getsentry/sentry-elixir

Issue simili

Altre issue su Elixir

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.