クロージャをメモリから解放する

JavaScriptでクロージャを構成したとき、メモリから解放されるのか。
4
think49 @think49

関数オブジェクトを代入した変数に null を代入しても、クロージャによる変数への参照は切れないらしい。 結論としては、参照を切る方法はない…のかな? http://ideone.com/gNwf8 #JavaScript

2010-10-11 17:58:35
think49 @think49

@think49 参照を切るというよりメモリから解放したかった。明示的に対象のオブジェクトをメモリから解放する方法はないものか…。

2010-10-11 18:08:40
think49 @think49

@think49 クロージャを作らなければ、関数実行完了と同時に使用した変数はメモリから解放される。 クロージャを作ると、document を unload するまでメモリを占有し続ける。

2010-10-11 18:09:21
think49 @think49

@think49 まず、クロージャを作る。クロージャが不要になったら関数オブジェクトを解放したかった。 何か良い方法はないかな…。

2010-10-11 18:11:13
Atsushi Takayama @edvakf

@think49 Chrome の話だったらちゃんと解放されますよ。不要になった瞬間じゃなくて定期的に掃除屋さんが走るはずです。あと他のことでメモリをいっぱい使ったときとかも。Safari とかだったら不要になった瞬間に解放されるらしいです。

2010-10-11 18:13:07
フォル @foldrr

@think49 ミクシィ以来お久しぶりです>< おっしゃる通り「変数i」に対する参照は切れませんが、fooが返すクロージャが解放用の関数を持てば、iをnullにすることはできると思います。もし勘違いしてたらごめんなさい。。。

2010-10-11 18:15:03
フォル @foldrr

@think49 さっきのは foo()の中で、return func; する前に例えば func.release = function(){ i = null; } するっていう意味でつぶやきました><

2010-10-11 18:16:58
think49 @think49

@edvakf @foldrr @foldrr ありがとうございます。実際に想定しているのは http://ideone.com/8M2th のようなケースです。 コールバック関数から変数への参照を切りたかったのですが、UA によっては解放処理を省けるということでしょうか。

2010-10-11 18:30:01
think49 @think49

複数人にReplyすると一番最後にReplyした人への返信扱いになるのか…。

2010-10-11 18:31:52
フォル @foldrr

@think49 解放処理の記述は必要になると思います。クロージャ自体は残ってしまいますから。さっき私がリプしたのは参照をきる方法についてで、参照を「自動的に」切る方法ではないんです。。。

2010-10-11 18:34:45
think49 @think49

@think49 result がグローバル変数になってますが、ローカル変数の宣言を忘れてました。

2010-10-11 18:35:21
フォル @foldrr

@think49 頭にドットスペース ". " 付けるとかですかね〜。

2010-10-11 18:36:19
think49 @think49

@foldrr すみません。まとめてReplyしたのが拙かったですね。 明示的に切る方法は理解していて、それはコードで示したつもりでした。 「UAによっては」の部分は @edvakf さんが指摘された「Chrom だと定期的に掃除やさんが走る」に対するReplyのつもりでした。

2010-10-11 18:41:21
フォル @foldrr

@think49 str = map = nullは必要ない、というか書いても意味が無さそうに思えます。strはhoge()ローカルで勝手に消えるし、mapはクロージャが参照しているからnullを入れてもオブジェクトは残り続けるので。

2010-10-11 18:41:23
Atsushi Takayama @edvakf

@think49 return result した時点で中の変数や関数はどこからもアクセスできない状態になっていますので、全部まとめて解放されるはずです。たぶん v8 でも hoge を抜けるときに全部解放されてると思いますが、確証があるわけではありません。

2010-10-11 18:42:48
フォル @foldrr

@think49 私こそ突然横やりいれちゃってお騒がせしました>< UAのGCまでは考慮せずに参照がどうなるかという点だけでリプしちゃいました。

2010-10-11 18:44:42
think49 @think49

@edvakf なるほど。「どこからもアクセスできない状態 = 解放される」なんですね。 私は「クロージャ = メモリから解放されない」というイメージでいました。勉強になりました。

2010-10-11 18:49:20
think49 @think49

@foldrr 私は IE6 のメモリリークパターンが頭に残っていて、そのイメージだけで判断していたような気がします。考える機会が出来て良かったです。

2010-10-11 18:51:40
Atsushi Takayama @edvakf

@think49 http://j.mp/d6z5tP V8 資料にもどこからも使われない=解放されるとあります。V8 は世代別 GC なので、関数(その他スタックフレーム)を抜けても保持されているメモリについては一度別領域に移され、定期的に掃除屋が参照数を調べて解放します。

2010-10-11 18:54:08
フォル @foldrr

@think49 私はお恥ずかしいことにメモりリークパターンについてほとんど理解していませんでした。。。少しだけググってみましたがとても勉強になりました><

2010-10-11 19:00:33
think49 @think49

@foldrr リークパターンについては、http://goo.gl/D0r9 http://goo.gl/wT1E あたりが参考になると思います。 IE6SP3 で修正済みですが、個人的にはクロージャの仕組みを考えるいい機会になりました。

2010-10-11 19:17:28