Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What is Soft Memory Limit?

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

What is Soft Memory Limit?

Avatar for HiroyukiYagihashi

HiroyukiYagihashi

August 15, 2022
Tweet

More Decks by HiroyukiYagihashi

Other Decks in Technology

Transcript

  1. 自己紹介 - Hiroyuki Yagihashi - ソフトウェアエンジニア - maintidx - Maintainability

    Index を計測する静的解析ツール - Twitter: @yagipy_ - GitHub: @yagipy - Blog: https://blog.yagipy.me
  2. GCとは - 使わなくなったメモリを特定し再利用できるようにするシステム - Go GC は Tracing GC &

    Concurrent Mark Sweep - 大きく Mark フェーズと Sweep フェーズに分かれる - Mark フェーズ : アプリで使われているメモリオブジェクトを Mark - Sweep フェーズ : Mark されていないオブジェクトを Sweep - Stop The World( 通称 STW) が発生する https://en.wikipedia.org/wiki/Tracing_garbage_collection
  3. GCの実行コスト - GC の実行によって CPU コストが増え、メモリ使用量が減る - 主な CPU コスト

    - GC の実行コスト - ライブヒープのサイズに比例して増加するコスト (Mark のコスト ) - Sweep は高速であるため、コストを無視できるものとする - 主なメモリ使用量 - ライブヒープ : 前回 GC で Mark されたメモリ - ニューヒープ : Mark フェーズ前に割り当てられた新しいヒープメモリ - ライブヒープになるか、解放されるかは分からない - 実行すればするほど CPU コストが増え、メモリ使用量が減る - 実行しなければしないほど CPU コストが減り、メモリ使用量が増える https://tip.golang.org/doc/gc-guide#Understanding_costs
  4. Go GCの実行タイミング•頻度(1.18以前) 1. 前回の GC から 2 分後 2. 前回

    GC 後のライブヒープと同量をニューヒープが確保した時 ( ※ デフォルト ) - 2 は runtime/debug.SetGCPercent / GOGC で変更可能 - ニューヒープをどの程度確保したら GC を実行するかを比率で指定 ( デフォルトは 100%) - 前回のライブヒープを 100% とする https://tip.golang.org/doc/gc-guide
  5. GOGCと実行コストまとめ - GOGC が高い - GC 実行頻度が低くなるため、 CPU コストが減り、メモリ使用量が増える -

    GOGC が低い - GC 実行頻度が高くなるため、 CPU コストが増え、メモリ使用量が減る
  6. 具体例: GOGC=100 - 使えるメモリが 60MiB で、ライブヒープのスパイク時が 30MiB 、通常時は 10~20MiB の

    アプリを実行している場合 - 利用可能なメモリがあるにもかかわらず、 GOGC を 100 以上に増加させることはできない
  7. Go 1.18以前の主な解決策 - ヒープバラスト - アプリ起動時に大規模なメモリ割り当て ( バラスト ) を行い、一定以上のライブヒープを確保する

    - 例 (twitch) - プラットフォーム間で移植性がない - 適切なヒープバラストのサイズを見つける必要がある - 手動 GC - 通常は cgroups 等でのメモリ制限を行いつつ、その値に従って手動で GC を行う - 例 - 頻繁に呼び出すと、大きくパフォーマンスが低下してしまう可能性がある - アプリの進行に大きな影響を与える可能性があるため、十分な調査と検証が必要
  8. Soft Memory Limit - メモリ制限を設定することができる機能 - 設定したメモリ制限を超えないように GC が実行される -

    runtime/debug.SetMemoryLimit / GOMEMLIMIT で設定 - 整数 + 単位文字列を指定 ( 例 : “100B” 、 ”100MiB” 、 ”100MB” 、 etc…) - GOGC と GOMEMLIMIT は連動している - スパイク時はメモリ制限の値で制御し、プログラムの残りの実行は GOGC によって設定された値で制 御
  9. GCデススパイラルとその対策 - GC デススパイラル - ライブヒープが大きくなるにつれて、 GC 頻度が増加する - 最終的には連続で

    GC が実行され、 CPU 使用率が増加し、アプリの進行に問題が発生する - リーキーバケット機構を使用して、 GC の CPU 使用率が 50% 以下になるように GC アシ ストを無効化する - GC の CPU 時間分が累積し、アプリの CPU 時間分が放出されるバケットを持つ - バケットが満たされた場合 (GC の CPU 使用率を 50% を超えた場合 ) 、バケットが空になるまで goroutine は GC アシストをしない - GC アシスト : メモリ確保時に Mark フェーズのお手伝いをする機能 - リーキーバケット機構のコミット
  10. まとめ - Go 1.19 で Soft Memory Limit が追加された -

    GOMEMLIMIT を設定することにより、メモリ制限ができるようになった - Go 1.18 以前より GC を制御しやすくなった
  11. 参考文献 - リリースノート - Go GC ガイド (Go 1.19 で追加

    ) - Soft memory limit プロポーザル - HACKING.md - GitHub issue - Go 1.19 のメモリ周りの更新 | フューチャー技術ブログ