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

オープン 初心者向け
#1,259 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 2 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
76/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
elixir
領域
backend

調査の方向性

まず Sentry.Sources.handle_continue/2 を読み、特にパッケージ化されたマップをデコードしてエントリを ETS に挿入する :load_source_code_map 節を確認してください。GenServer コールバックのテストを調べ、読み込み後にプロセスがデコード済みマップを解放し、ETS エントリは引き続き利用できることを確認してください。Issue にはテストファイルが指定されていないため、リポジトリ内で関連するテストを探してください。

索引モデルが issue の本文から書いたものです。

説明

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.

主要言語
Elixir
スター
692
フォーク
219
平均マージ
2日 19時間
マージ済み PR(30日)
16

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

getsentry/sentry-elixir のほかの issue

getsentry/sentry-elixir の issue をすべて見る

似ている issue

Elixir の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。