ようちゃんのブログ

ようちゃんのブログはこちらです!

RubyKaigi: Symbol GC

nariさん
NaCl

GC本はAmazonでは絶版。達人出版会で買ってね!
http://tatsu-zine.com/books/gcbook

SymbolはID。

:symbol

シンボルの落とし穴

  • すべてのGCGCされない
  • 脆弱性につながる
    • ユーザーの入力をシンボルにすると…
    • Digest認証のヘッダーのキーをto_symしてシンボルにしていまうと…

シンボルがGCされるか?
他の言語をみても、されるのとされないのがある…

Scalaの例

symbolの実態はJavaのStringでSymbol Tableというハッシュテーブルで管理されていて、Weak Referenceで参照している。

Rubyの場合

symbolはFrozen Stringを参照していて、global_symbolsというハッシュテーブルで管理されている。<- C言語の領域
C言語側ではIDで参照している。

GCの対象になっていない。

なぜシンボルがGCされないのか…

GCするとglobal_symbolsのエントリも削除する。
そうするとC extensionのなかでIDで参照しているものが迷子になり、不整合が発生する。

Rubyの世界で死んだSymbolがCの世界では生きている

どうするか?

Immortal SymbolとMotal symbolにわける

:sym -> Immortal

いままでとはあまり変わらないねー

"sym".to_sym -> Mortal

global_symbolsのなかで、IDではなく、symbolとして格納される

同名のImmortal symbolがある場合

Immortal symbolがあって、同名で"sym".to_symとかすると、ImmortalがMortalに化ける。

from Mortal to Immortal

メソッドを定義するとき
define_method("foo".to_sym){}
(メソッドはIDで参照しているから?)MortalがImmortalに化ける。

A new pitfall comming!

Immortal SymbolはGCされない
Motal -> Immortal への変換がおこることがある

質疑
Q: メソッド他にIDが要求される場合はない?

A: Rubyあんまり書かないので、わからない。出してみてなにかみつかるかも