Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
RBSのメモリ使用量改善への道
Search
pocke
July 27, 2024
Technology
1
51
RBSのメモリ使用量改善への道
pocke
July 27, 2024
Tweet
Share
More Decks by pocke
See All by pocke
プログラミングで遊ぶ
pocke
0
73
Witchcraft for Memory
pocke
1
4k
The path to memory reduction in RBS
pocke
0
47
Community-driven RBS repository
pocke
2
1.4k
Active Record Query Quiz
pocke
1
1.6k
Let's write RBS!
pocke
1
5.2k
RBS and Rails, Present and Future
pocke
1
1.4k
The newsletter of RBS updates
pocke
1
3.4k
kwargs warning → Sentry
pocke
0
350
Other Decks in Technology
See All in Technology
ググるより、AIに聞こう - Don’t Google it, ask AI
oikon48
0
910
データとAIで未来を創るDatabricks - 君の可能性を加速させるプラットフォーム
taka_aki
0
110
JJUG CCC 2025 Fall バッチ性能!!劇的ビフォーアフター
hayashiyuu1
1
330
⽣成 AI で進化する AWS オブザーバビリティ
o11yfes2023
0
120
大規模プロダクトで実践するAI活用の仕組みづくり
k1tikurisu
4
1.1k
QAセントラル組織が運営する自動テストプラットフォームの課題と現状
lycorptech_jp
PRO
0
420
Lazy Constant - finalフィールドの遅延初期化
skrb
0
210
エンジニアに定年なし! AI時代にキャリアをReboot — 学び続けて未来を創る
junjikoide
0
180
機密情報の漏洩を防げ! Webフロントエンド開発で意識すべき漏洩パターンとその対策
mizdra
PRO
9
3.4k
Moto: Latent Motion Token as the Bridging Language for Learning Robot Manipulation from Videos
peisuke
0
150
生成AIではじめるテスト駆動開発
puku0x
0
100
内部品質・フロー効率・コミュニケーションコストを悪化させ現場を苦しめかねない16の組織設計アンチパターン[超簡易版] / 16 Organization Design Anti-Patterns for Software Development
mtx2s
2
1.7k
Featured
See All Featured
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
320
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
140
34k
Large-scale JavaScript Application Architecture
addyosmani
514
110k
Facilitating Awesome Meetings
lara
57
6.6k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
8.1k
[RailsConf 2023] Rails as a piece of cake
palkan
57
6.1k
Imperfection Machines: The Place of Print at Facebook
scottboms
269
13k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.7k
Building an army of robots
kneath
306
46k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Docker and Python
trallard
46
3.6k
Become a Pro
speakerdeck
PRO
29
5.6k
Transcript
RBSのメモリ使用量改善 への道 岡山Ruby, Ruby on Rails勉強会 #23
誰 • Pocke • Ruby committer • RBSのメンテナ • 2020年から岡山に住んでいます
Agenda メインのトピックが2つ • ファイル数が多い時に、Steepの実行速度を改善した話 • Ruby向けのメモリプロファイラを作っている話
なぜメモリ使用量の改善が必要なのか
なぜメモリ使用量の改善が必要なのか • Steepはメモリをたくさん使う ◦ LSP Serverとしてプロセスが常駐する ◦ 1プロセスあたり 1.5GB ▪
* LSPが立ち上がっているプロジェクト数 ▪ * CPUの数(並列化するため) • Steepを広く使ってもらうにはメモリ使用量改善が必要
Steepの実行速度を改善した話
Steepの実行速度を改善した話 • Steepのメモリ使用量の改善に取り組んでいたら、その 副産物として実行速度の改善ができた ◦ メモリ使用量の改善はまだ…… • これはこれで面白かったので、紹介します • (来週この内容でブログ記事を公開するよ)
メモリのプロファイリング • SamSaffron/memory_profilerを使う • すべてのメモリの確保と、確保したまま残っているメモ リを表示してくれる
memory_profiler の結果
memory_profiler の結果 set.rbがめちゃくちゃメモリを使っている!
わかった問題 • set.rb がメモリをたくさん確保している ◦ 全体のメモリ確保の70%ぐらいがここで確保されている • これを直せれば問題が解決できるかも!
わかっていないこと • set.rb のコードがどこから呼ばれているのかが分から ない • これがわからないとSteepのどこを直したらよいのかが 分からない
Rubyの雑パッチを書いた https://gist.github.com/pocke/7499e5799856393 b930684ebb905d41c
雑パッチ • MemoryProfilerは ObjectSpace.allocation_sourcefile などを使っ ている • このメソッドが位置情報を取得するところにパッチする ◦ 取得した位置情報がset.rbならば、バックトレースを1つ遡る
雑パッチ
再度memory_profilerを実行
再度memory_profilerを実行 Steepのどこがメモリを確保しているのかわかった!
None
None
None
実行速度の問題が解決された💪 https://github.com/soutaro/steep/pull/1184 でもメモリ使用率はまだ未解決…
新しいメモリプロファイラ
今までの反省点 • メモリ使用量を改善するつもりが、実行速度の改善に なってしまっていた • memory_profilerで正しく問題を捉えられていなかっ た
今までの反省点(2) • memory_profilerで見ていた指標は「すべてのメモリ 確保」 • 一方でメモリ使用量の削減のために知りたいのは「メモ リ使用量がピークの時にメモリを使っているオブジェク ト」 • ここでずれがあった
◦ たくさん確保されてはすぐ消えるオブジェクトがノイズとなっていた
これに対するアプローチ • 長生きしたオブジェクトに絞って、メモリのプロファイ リングをできるとよいのでは • つまり、GCを生き残ったオブジェクトに注目する
メモリプロファイラを作った https://github.com/pocke/majo • GCを1回でも生き残ったオブジェクトだけを集めて集計す るプロファイラ • 一応まともに使えるので、v1.0.0をリリース済み
使ってみた感想 • 出る情報はmemory_profilerと近い ◦ しかし「長生きしたオブジェクト」しか結果に含まれないので、ノイズ がないことがわかるのが大きい ◦ 案外どれが長生きでどれが短命なのかは自明ではない • CSV出力が意外とかなり便利
◦ もしくはスプレッドシートが便利とも言える • memory_profilerに比べると若干高速 ◦ 「全オブジェクト」を対象にするmemory_profilerはかなり遅い ◦ 一方で短命オブジェクトを無視できるMajoは若干マシ
余談(1) memory_profilerのretainedを見るんじゃだめだった の? • retainedを見るにはオブジェクトを生かしておく必要が あり、memory_profilerを差し込む場所を考えるのが むずかしい… • 「メモリ使用量がピークの時」にmemory_profilerを 止めないといけない
余談(2) • https://github.com/ruby/ruby/pull/10598 ◦ RubyのMajor GCだけを止めて、Minor GCのみを動かす機能追加のPR • 最初実現方法を考えている時に、このPRも試せないかな と眺めていた
• 結果としては使わなかったけれど、PRでバグ報告をした りしていい経験になった