Gauche:シンボルのgc
kouさんのところで、uriのパーズ結果をシンボルとして返した場合の問題点として、 Shiroが次のように述べた。
- Shiro (2004/07/09 20:31:23 PDT): symbolで返ったほうが多少便利なのはわかるのですが、 一度internされたシンボルはgcされないので、サーバプログラムに使った場合、 外部からscheme部分をランダムに生成したuriを大量に食わされると問題となる可能性が あります。
これに対し、シンボルをgcしても問題はないのでは? という指摘が。
- なんでinternされたシンボルをgcしないの?
- Shiro: 勝手にgcしちゃうと、eq?で 比較できなくなりますよね。同じ名前のシンボルはeq?で比較できるという 前提がある限り、gcできないと思います。CommonLispみたいにuninternedな symbolを許すとか、パッケージでもって実質的にシンボルテーブルを複数持つ とかすれば別ですが。
- gcできるなら問題ないのでは?
(eq? 'symbolA 'symbolA) => #t (gc) (eq? 'symbolA 'symbolA) => #t
ってしたときに最初の式のsymbolAがgcで回収されて、最後の式で新たにinternされたsymbolAが作られる。 最初のsymbolAと最後のsymbolAはeq?をとったら#fになるけど、gcされるのならどこにも束縛されていないのだからeq?に持って行きようがない。 - Shiro: わ、こりゃ目から鱗だ。シンボルテーブルをweak hashにしておけば いいのか。比較が入る場合は必ずシンボルテーブル以外から参照されているわけだから。
- でも、このケースの使い方(シンボル名を文字列として使う場合)はともかくとして、
一般にはシンボルに束縛されている値が重要であって、
シンボルがどっかから指されてないからと言って gc してしまうのは困りますよね?
シンボルはいつ呼ばれるかは不明ですから。cut-sea:2004/07/13 02:57:07 PDT- と思ったら、(symbol? 'a) => #t なのに 'a だけじゃシンボルテーブルには intern されないのね ?cut-sea
- Shiro(2004/07/13 03:01:20 PDT): 伝統的なLispのモデルだとシンボルオブジェクトに 値スロットがあるんですが、Gaucheの場合、シンボルは単にハッシュテーブルに 登録された文字列にすぎず、各モジュールがシンボル→値のマッピングを持つ ことがグローバルな値の束縛になっています。つまり、グローバルに束縛されている シンボルは、必ずどこかのモジュール中の束縛テーブルから指されているので、 gcされることがありません。 なお、シンボルのintern (ハッシュテーブルへのシンボル名の登録) は シンボルオブジェクトが作られた時点で行われるので、 'a という式をreadしたらその時点でシンボルはinternされます。
- あー、そっか。やっぱり勘違いしてました。すんません。
gosh> 'a ;; (1) a gosh> (define a 123) ;; (2) 123
ここで(1)はシンボルのinternはされているけど、シンボル a に対する束縛対はないよ。 (2)ではシンボル a に対する束縛対(シンボルaと値123実体への対)がトップレベル環境に 生成される。 で、 gc して良いのは intern のみの状態ってことですね。 束縛対があれば、そいつがシンボル a へのポインタを含むので gc 対象外と。cut-sea:2004/07/13 04:44:34 PDT
Tag: GC