Rubyのweakrefが重い
たまたまweakrefのサンプルコードを書いていたら、Rubyのweakrefが非常に重いことに気がついた。
なんで。weakrefってただの弱参照リファレンスじゃないの。参照カウンタを回さない参照じゃないの。
Rubyに詳しくないからわからないけど、ちょっと調べてみた。
- 作者: Rubyサポーターズ,すがわらまさのり,寺田玄太郎,三村益隆,近藤宇智朗,橋立友宏,関口亮一
- 出版社/メーカー: 技術評論社
- 発売日: 2013/08/10
- メディア: 大型本
- この商品を含むブログ (16件) を見る
まずテストしたのは下のようなコード。
require 'weakref' p ObjectSpace.count_objects() ref = WeakRef.new(Object.new) p ObjectSpace.count_objects()
また単純。
そして、これを実行してみる。
$ ruby weakref.rb
{:TOTAL=>17581, :FREE=>322, :T_OBJECT=>7, :T_CLASS=>559, :T_MODULE=>22, :T_FLOAT=>7, :T_STRING=>6899, :T_REGEXP=>25, :T_ARRAY=>1450, :T_HASH=>20, :T_BIGNUM=>3, :T_FILE=>13, :T_DATA=>547, :T_MATCH=>110, :T_COMPLEX=>1, :T_NODE=>7576, :T_ICLASS=>20}
{:TOTAL=>17581, :FREE=>249, :T_OBJECT=>9, :T_CLASS=>559, :T_MODULE=>22, :T_FLOAT=>7, :T_STRING=>6961, :T_REGEXP=>25, :T_ARRAY=>1455, :T_HASH=>23, :T_BIGNUM=>3, :T_FILE=>13, :T_DATA=>548, :T_MATCH=>110, :T_COMPLEX=>1, :T_NODE=>7576, :T_ICLASS=>20}$ ruby2.0 weakref.rb
{:TOTAL=>27253, :FREE=>194, :T_OBJECT=>49, :T_CLASS=>558, :T_MODULE=>23, :T_FLOAT=>4, :T_STRING=>9700, :T_REGEXP=>66, :T_ARRAY=>1994, :T_HASH=>70, :T_BIGNUM=>3, :T_FILE=>24, :T_DATA=>885, :T_MATCH=>21, :T_COMPLEX=>1, :T_RATIONAL=>2, :T_NODE=>13636, :T_ICLASS=>23}
{:TOTAL=>27253, :FREE=>118, :T_OBJECT=>51, :T_CLASS=>558, :T_MODULE=>23, :T_FLOAT=>4, :T_STRING=>9765, :T_REGEXP=>66, :T_ARRAY=>1999, :T_HASH=>73, :T_BIGNUM=>3, :T_FILE=>24, :T_DATA=>886, :T_MATCH=>21, :T_COMPLEX=>1, :T_RATIONAL=>2, :T_NODE=>13636, :T_ICLASS=>23}
Ruby1.9とRuby2.0で試してみたけど同様。おもむろにFREEが減ってる。
仕方がないのでweakrefの実装を見ると、weakref.rbでdelegate.rbを継承していて、そしてdelegate.rbがゴニョゴニョしててよくわからなかった。まぁ、Rubyを使わない私からするとわかるはずもないが、なんかRubyで色々してるっぽい。
よってweakrefを実装しているコードがバックグラウンドでリソースを消費するっぽい。
うーん。weakrefは無駄なメモリを使わないために使うことも多いと思うんだけど、これだと小さなオブジェクトだとweakrefを使わないほうがメモリ消費が少ない気もする。
うーーん。weakrefは説明するのも面倒くさいけど、実装するのも面倒くさいのかな。
うーーーん。weakrefの説明書いてたけど書く気無くしたのでこの文章だけ公開しとく。
- 作者: すがわらまさのり,前島真一,近藤宇智朗,橋立友宏
- 出版社/メーカー: 技術評論社
- 発売日: 2014/06/06
- メディア: 大型本
- この商品を含むブログを見る