Let's start Scheme

2014-10-18

Weak hashtable



こういったいきさつがあって、シンボル(とその他2つ)をGC対象にしたのだが、どうもweak hashtableの実装がまずいらしく、多少改善された程度のメモリー消費量にしかなっていない。とりあえず実装を見直してみると、weah hashtableとhashtableの実装上にweak boxを載せてそれっぽく見せているのだが、どうもこのweak boxが消えないのでエントリー数が増え続けるという感じみたいである。一応キーが回収された際にエントリーを消すような小細工がされてはいるのだが、なぜか上手く動いていない感じである。

どうするか?というのがあるのだが、解決方法は2つくらい案があって、
  1. Weak hashtableを別実装にしてしまう。
    hashtable-ref等の手続きを共有して使えないのだからコードを共有する必要があまりなくね?という発想。
  2. Hashtable側のAPIをリッチにする
    バケツの割り当て等を外部から操作できるようにしてしまえば何とかなりそうじゃね?という発想。
1は多分楽なんだけど、後々のことを考えると(主にメンテ)ある程度のコードは共有しておきたい気もする。2は茨の道なんだけど(パフォーマンスとか)、上手く作ればメンテが楽になりそう。

どちらの道をとったとしても、weak boxの扱いをどうするかという問題は残るのでこれはちと考える必要がある。

追記(2014年10月18日)
よく考えてみればエントリー数が減らないのはweak hashtableの値がGCされた際に対象のエントリーを削除しないのが問題なので、値がGCされた際に対象のエントリーを削除するように変更した(後方互換を保つためにフラグを一個追加した)。なんとなく、動いているっぽいので当面はこれでよしとしよう。

2 comments:

Shiro Kawai said...

Key-weakなhashtableは面倒ですよね。finalizerでGCされたエントリ削除してますか? Gaucheだとどのスレッドでfinalizerが呼ばれるかが不定なので安全にハッシュテーブルにアクセスすることができず、どうしようか迷ってて止まってます。(多分、通常のアクセスのタイミングで空のweak boxを見つけたら随時回収してゆく、あたりが落としどころかなとは思いますが、refするだけで構造を変更するのもちと気持ち悪い)

kei said...

finalizerでエントリ削除かつ明示的なdeleteでfinalizerの削除してます。なので多少パフォーマンスが悪いのが辛いところですね。今回の変更でvalue-weakかつエントリ削除が入ったのでさらにパフォーマンスが・・・
スレッドはそういえば頭からすっぽり抜けてました。う~ん、問題になるかなぁ。

Post a Comment