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

What is Soft Memory Limit?

What is Soft Memory Limit?

HiroyukiYagihashi

August 15, 2022
Tweet

More Decks by HiroyukiYagihashi

Other Decks in Technology

Transcript

  1. What is Soft Memory Limit?
    Hiroyuki Yagihashi @ Go 1.19 Release Party
    🎉

    View Slide

  2. 自己紹介
    - Hiroyuki Yagihashi
    -
    ソフトウェアエンジニア
    - maintidx
    - Maintainability Index
    を計測する静的解析ツール
    - Twitter: @yagipy_
    - GitHub: @yagipy
    - Blog: https://blog.yagipy.me

    View Slide

  3. アジェンダ
    - Go GC
    の概要
    -
    背景
    - Soft Memory Limit

    View Slide

  4. ゴール
    - Go GC
    の概要を理解する
    - Soft Memory Limit
    導入の背景と機能を理解する

    View Slide

  5. Go GCの概要

    View Slide

  6. 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

    View Slide

  7. GCの実行コスト
    - GC
    の実行によって
    CPU
    コストが増え、メモリ使用量が減る
    -
    主な
    CPU
    コスト
    - GC
    の実行コスト
    -
    ライブヒープのサイズに比例して増加するコスト
    (Mark
    のコスト
    )
    - Sweep
    は高速であるため、コストを無視できるものとする
    -
    主なメモリ使用量
    -
    ライブヒープ
    :
    前回
    GC

    Mark
    されたメモリ
    -
    ニューヒープ
    : Mark
    フェーズ前に割り当てられた新しいヒープメモリ
    -
    ライブヒープになるか、解放されるかは分からない
    -
    実行すればするほど
    CPU
    コストが増え、メモリ使用量が減る
    -
    実行しなければしないほど
    CPU
    コストが減り、メモリ使用量が増える
    https://tip.golang.org/doc/gc-guide#Understanding_costs

    View Slide

  8. Go GCの実行タイミング•頻度(1.18以前)
    1.
    前回の
    GC
    から
    2
    分後
    2.
    前回
    GC
    後のライブヒープと同量をニューヒープが確保した時
    (
    ※ デフォルト
    )
    - 2

    runtime/debug.SetGCPercent / GOGC
    で変更可能
    -
    ニューヒープをどの程度確保したら
    GC
    を実行するかを比率で指定
    (
    デフォルトは
    100%)
    -
    前回のライブヒープを
    100%
    とする
    https://tip.golang.org/doc/gc-guide

    View Slide

  9. GOGCと実行コストまとめ
    - GOGC
    が高い
    - GC
    実行頻度が低くなるため、
    CPU
    コストが減り、メモリ使用量が増える
    - GOGC
    が低い
    - GC
    実行頻度が高くなるため、
    CPU
    コストが増え、メモリ使用量が減る

    View Slide

  10. 背景

    View Slide

  11. Go 1.18以前
    - GOGC

    GC
    の動作を変更するために使用できる唯一のパラメータ
    -
    実際に使用できるメモリが有限であることを考慮したパラメータではない
    - GOGC
    は使用可能メモリ量は知らず、比率によってのみ動作が決定する

    View Slide

  12. ライブヒープにスパイクが発生するケース
    - CPU
    使用率を低くするために、
    GOGC
    を高く設定したくてもできない
    -
    ライブヒープのスパイクを考慮して設定しなければならない
    -
    アプリによってはスパイクの予測が困難
    -
    予期せぬタイミングで
    Out Of Memory
    が発生してしまう可能性がある

    View Slide

  13. 具体例: GOGC=100
    -
    使えるメモリが
    60MiB
    で、ライブヒープのスパイク時が
    30MiB
    、通常時は
    10~20MiB

    アプリを実行している場合
    -
    利用可能なメモリがあるにもかかわらず、
    GOGC

    100
    以上に増加させることはできない

    View Slide

  14. 具体例: GOGC=200
    -
    通常時
    (20MiB)

    60MiB
    まで使えるようになるが、スパイクが発生すると
    90MiB
    にな
    るため
    Out Of Memory
    が発生する

    View Slide

  15. Go 1.18以前の主な解決策
    -
    ヒープバラスト
    -
    アプリ起動時に大規模なメモリ割り当て
    (
    バラスト
    )
    を行い、一定以上のライブヒープを確保する
    -

    (twitch)
    -
    プラットフォーム間で移植性がない
    -
    適切なヒープバラストのサイズを見つける必要がある
    -
    手動
    GC
    -
    通常は
    cgroups
    等でのメモリ制限を行いつつ、その値に従って手動で
    GC
    を行う
    -

    -
    頻繁に呼び出すと、大きくパフォーマンスが低下してしまう可能性がある
    -
    アプリの進行に大きな影響を与える可能性があるため、十分な調査と検証が必要

    View Slide

  16. 問題点
    -
    ライブヒープにスパイクが発生するケースで、
    CPU
    使用率が必要以上に高くなってし
    まう

    View Slide

  17. Soft Memory Limit

    View Slide

  18. Soft Memory Limit
    -
    メモリ制限を設定することができる機能
    -
    設定したメモリ制限を超えないように
    GC
    が実行される
    - runtime/debug.SetMemoryLimit / GOMEMLIMIT
    で設定
    -
    整数
    +
    単位文字列を指定
    (

    : “100B”

    ”100MiB”

    ”100MB”

    etc…)
    - GOGC

    GOMEMLIMIT
    は連動している
    -
    スパイク時はメモリ制限の値で制御し、プログラムの残りの実行は
    GOGC
    によって設定された値で制

    View Slide

  19. ライブヒープにスパイクが発生するケース(設定前)
    - Soft Memory Limit
    設定前

    View Slide

  20. ライブヒープにスパイクが発生するケース(設定後)
    - 60MiB
    を超えることなく、
    CPU
    使用率が低下

    View Slide

  21. 問題点
    -
    ライブヒープにスパイクが発生するケースで、
    CPU
    使用率が必要以上に高くなってし
    まう
    - Soft Memory Limit
    を設定することで解決 🎉

    View Slide

  22. 補足
    - Go
    ヒープとランタイムが管理する全てのメモリが対象
    -
    他言語で管理されるメモリや
    OS
    が保持するメモリは対象外
    -
    特定のメモリ量のコンテナに
    Web
    サービスを展開する場合、
    5~10%
    の余裕を持たせ
    て設定することを推奨

    View Slide

  23. Soft Memory Limitに関連するTips
    - GOGC=off
    - GC
    デススパイラルとその対策

    View Slide

  24. GOGC=off
    - Soft Memory Limit
    は機能する
    -
    メモリ制限を保つために必要な、最小限の
    GC
    回数を設定できる

    View Slide

  25. GCデススパイラルとその対策
    - GC
    デススパイラル
    -
    ライブヒープが大きくなるにつれて、
    GC
    頻度が増加する
    -
    最終的には連続で
    GC
    が実行され、
    CPU
    使用率が増加し、アプリの進行に問題が発生する
    -
    リーキーバケット機構を使用して、
    GC

    CPU
    使用率が
    50%
    以下になるように
    GC
    アシ
    ストを無効化する
    - GC

    CPU
    時間分が累積し、アプリの
    CPU
    時間分が放出されるバケットを持つ
    -
    バケットが満たされた場合
    (GC

    CPU
    使用率を
    50%
    を超えた場合
    )
    、バケットが空になるまで
    goroutine

    GC
    アシストをしない
    - GC
    アシスト
    :
    メモリ確保時に
    Mark
    フェーズのお手伝いをする機能
    -
    リーキーバケット機構のコミット

    View Slide

  26. まとめ
    - Go 1.19

    Soft Memory Limit
    が追加された
    - GOMEMLIMIT
    を設定することにより、メモリ制限ができるようになった
    - Go 1.18
    以前より
    GC
    を制御しやすくなった

    View Slide

  27. 参考文献
    -
    リリースノート
    - Go GC
    ガイド
    (Go 1.19
    で追加
    )
    - Soft memory limit
    プロポーザル
    - HACKING.md
    - GitHub issue
    - Go 1.19
    のメモリ周りの更新
    |
    フューチャー技術ブログ

    View Slide