カラム追加で増えるActiveRecordのメモリサイズ イメージできますか?
by
asayamakk
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
GMOビューティー株式会社 浅山 広大 カラム追加で増える ActiveRecordの メモリサイズ イメージできますか?
Slide 2
Slide 2 text
● 1インスタンスあたり何バイト増えるのか 答え・調べ方・どんなオブジェクトが生成されるか ● Rubyのメモリのレイアウトについて Rubyのメモリ管理方法(基礎編、最近のアップデート編) 一歩目の踏み出し方 この発表の構成
Slide 3
Slide 3 text
● Railsで開発していて、メモリ効率・使用量を意識し てARインスタンスを生成するようになる ● CRubyの仕組みに興味を持つきっかけになること この発表のゴール・目的
Slide 4
Slide 4 text
特に断りのない場合 Ruby 3.0, MRI (CRuby), Rails7.1, 64bit CPU での話をしています 前提
Slide 5
Slide 5 text
🤔< clinicsって参照多いテーブルだけど このコード、どれぐらいメモリ使用量増えるのかな? きっかけ
Slide 6
Slide 6 text
add_columnすると 何バイト増えるのか (integerの場合)
Slide 7
Slide 7 text
224バイト
Slide 8
Slide 8 text
ObjectSpace.memsize_of を使う → インスタンスが持つインスタンス変数までは追えない オブジェクトのメモリサイズの調べ方
Slide 9
Slide 9 text
ObjectSpace.reachable_objects_from を使う ● あるオブジェクトから直接辿れるオブジェクトを返す ○ 1階層しか辿れないので、探索的に取得する必要がある ○ ObjectSpace.#reachable_objects_from (Ruby 3.3 リファレンスマニュアル) ○ https://www.atdot.net/~ko1/diary/201212.html#d8 オブジェクトのメモリサイズの調べ方
Slide 10
Slide 10 text
startから辿れる全てのオブジェクトを取得 https://www.atdot.net/~ko1/diary/201212.html#d8 より引用(一部改変)
Slide 11
Slide 11 text
インスタンスのメモリサイズの調べ方 PK+timestamps のARインスタンス → 3716 byte (≒3.6KB)
Slide 12
Slide 12 text
インスタンスのメモリサイズの調べ方 integerを追加して、追加前後での比較 → 224byte 増加
Slide 13
Slide 13 text
何が増えたか
Slide 14
Slide 14 text
増えたオブジェクトを調べる integerの追加前後での比較 String (40byte), ActiveModel::Attribute::FromDatabase (72byte) ActiveModel::Type::Integer (72byte), Range (40byte)
Slide 15
Slide 15 text
増えたオブジェクトを調べる ①String ②AMの中のTypeの 中のRange
Slide 16
Slide 16 text
● ActiveModel::Attributeの内部クラス ● ActiveRecordの@attributesの@attributesに格納されている ● DBからの結果をラップする (typeを持っており、型変換も担う) ActiveModel::Attribute::FromDatabaseはどこから? 定義 取得 参考: 【Rails 6.1】AS 句で作ったカラムに DB の型情報はない - ESM アジャイル事業部 開発者ブログ
Slide 17
Slide 17 text
増えたオブジェクトを調べる ⇨ 合計で224バイト増
Slide 18
Slide 18 text
増えたオブジェクトを調べる
Slide 19
Slide 19 text
CRubyのメモリレイアウトの話
Slide 20
Slide 20 text
> Ruby で扱える全ての値はオブジェクトです ● CRubyではオブジェクトごとに RVALUEと呼ばれる固定長のメモリを割り当て (例外あり) ⇨ RVALUEによってオブジェクトの値を表現 ● RVALUEへのポインタをVALUEと呼ぶ (ポインタじゃないときあり) ● VALUEはポインタを格納するので、64bit CPUで8バイト ● RVALUEはVALUE 5つ分のサイズ (ヘッダー2つ+ボディ3つ) 8 × 5 = 40byte そもそもオブジェクトって何ですか?
Slide 21
Slide 21 text
RString構造体 ● 文字列が23バイト以内で表せる場合 → RVALUE内に埋め込み (40byte) ● 24バイト以上の場合 → len: バイト列の長さ ptr: バイト列 (mallocで確保される) capa: malloc - 1 (終端文字分を引く)
Slide 22
Slide 22 text
● ● RStruct構造体を使って表現 ● bodyに3つのVALUE → 始点・終点・終点を含むかどうか RStruct構造体 (Rangeの例)
Slide 23
Slide 23 text
増えたオブジェクトを理解する ⇨ 合計で224バイト増
Slide 24
Slide 24 text
● ● RObject構造体を使って表現 ● インスタンス変数が3つ以下 → RObject内に埋め込み ● 4つ以上の場合 → ivptr (配列) に値を確保 (malloc) 40(RObject) + 8×4 (ivptrで確保した配列) ⇨ 72byte RObject構造体 (ユーザー定義クラス ActiveModel::Attribute::FromDatabaseなど )
Slide 25
Slide 25 text
増えたオブジェクトを理解する ⇨ 合計で224バイト増
Slide 26
Slide 26 text
残りの疑問
Slide 27
Slide 27 text
> Ruby で扱える全ての値はオブジェクトです ● CRubyではオブジェクトごとに RVALUEと呼ばれる固定長のメモリを割り当て (例外あり) ⇨ RVALUEによってオブジェクトの値を表現 ● RVALUEへのポインタをVALUEと呼ぶ (ポインタじゃないときあり) ● VALUEはポインタを格納するので、64bit CPUで8バイト ● RVALUEはVALUE 5つ分のサイズ (ヘッダー2つ+ボディ3つ) そもそもオブジェクトって何ですか?
Slide 28
Slide 28 text
VALUE埋め込み表現 (即値、immediate value) ● VALUEはポインタ、ではないときがある ● ポインタとしてありえない値を使って、VALUEのみで値を表現 ポインタの場合: 下位3bitは必ず0 (8の倍数) ⇨ 下位3bitに1が含まれるときは、VALUE埋め込み表現 ● 例: Fixnum (整数値) ○ VALUEの下位1bitが1のとき ○ 残りの63bitで整数値を表現 ⇨ -2^62 ~ 2^62 の範囲で表現可能 (FixnumとBignumの境目)
Slide 29
Slide 29 text
増えたオブジェクトを理解する ⇨ 合計で224バイト増
Slide 30
Slide 30 text
特に断りのない場合 Ruby 3.0, MRI (CRuby), Rails7.1, 64bit CPU での話をしています 前提
Slide 31
Slide 31 text
● Ruby 3.2 から埋め込み表現可能な範囲が広がっています VWA (Variable Width Allocation) Optimizing Ruby’s Memory Layout: Variable Width Allocation - Shopify https://shopify.engineering/ruby-variable-width-allocation
Slide 32
Slide 32 text
VWA (Variable Width Allocation) ● Size Pool という新しい概念が増えた ○ RVALUEが格納されるslotのサイズが 40, 80, 160, 320, 640byte のどれかに ● 埋め込み可能なデータの拡張 ○ String: 615byteまで埋め込み可能に ○ Object: 78個のivarまで埋め込み可能に
Slide 33
Slide 33 text
● Rubyのウラガワ (Web+DB Press連載記事) ○ 笹田さんの連載 ○ Rubyのメモリレイアウトをベースにどんな最適化がされ てきたかを解説されてる ● RHCの参考文献を読み漁る ○ 笹田さんの活動 ○ https://github.com/ko1/rubyhackchallenge/blob/ma ster/bib.md 参考資料 (CRubyを理解する第一歩として)
Slide 34
Slide 34 text
まとめ
Slide 35
Slide 35 text
add_columnすると 何バイト増えるのか (integerの場合)
Slide 36
Slide 36 text
224バイト
Slide 37
Slide 37 text
224バイト RVALUEが4個と ivptrでVALUE 4*2個 ActiveModel::Attribute::FromDabase (40+32), ActiveModel::Type::Integer (40+32), String (40), Range(40)
Slide 38
Slide 38 text
私たちのスキーマ設計
Slide 39
Slide 39 text
おまけ
Slide 40
Slide 40 text
自己&会社紹介
Slide 41
Slide 41 text
自己紹介 浅山 広大 (asayamakk) GMOビューティーで取締役エンジニアをやってます 趣味は美容医療とキックボクシングと3Dゼルダです。
Slide 42
Slide 42 text
おトクな割引クーポンの 購入サイト "美容医療で私らしく" 美容医療の検索・予約サービ ス 予約管理から電子カルテ・ 会計までを一括管理 3 つ の 提 供 サ ー ビ ス キレイパスなら、あなたにぴったりな 施術や美容クリニックが見つかる。 チケット購入から予約まで、スムーズ な体験を提供します。 クリニックのDXを加速させ効率的な オペレーションと経営サポートを実現 する美容クリニックの経営支援プラッ トフォームです。 ビューティーサロン・ 美 容 クリニック ・グルメ・ 宿 泊 ・ 通 販 など、 様 々な ジャンルの割引クーポンを掲載中! 毎 日お昼の12時に、新 着のおトクな クーポンが登場します。
Slide 43
Slide 43 text
ブース&この後のセッションでもお会いしましょう!