メモリの浪費を避けるコーディング、を読んだ感想
【JavaScript】メモリの浪費を避けるコーディング | ヘッドウォータースのブログ TechNote を読んだ感想。
最初にお詫びしておきます。かなり批判的になってしまいました。
JavaScriptオブジェクトについては、ガベージコレクタ方式が採用されています。ガベージコレクタは以下のタイミングでメモリの開放を行います。
- 変数に対し、明示的にnullをセットした時
- 関数の実行終了時
- 上記以外は任意のタイミング(JavaScriptエンジンによっては、ガベージコレクタを呼出すメソッドが用意されている)
「ガベージコレクタ方式」という方式はなくて、ここで言いたいのは Mark & Sweep とか、そういうことだと思います。ただ、JaavScript 処理系の実装によって、どのような GC が実装されているかはまちまちなので、具体名を挙げないと言及できません。
開放のタイミングもなんだか微妙に違います。
DOMオブジェクトについては、参照カウンタ方式が採用されています。
これも処理系依存で、どのような GC であるかは一概には言えません。
アクティベーションオブジェクトとは関数のコールが発生した際に、自動的に生成されるオブジェクトです。
これは知りませんでした。勉強になりました。
循環参照が発生すると参照カウンタが0にならず、ブラウザを閉じるまでメモリが解放されずに残ってしまいます。
これは私の認識と違っていました。JavaScript のセッションは画面遷移単位だと思っていたので、画面遷移すれば開放されるものだという認識でした。もしかするとブラウザプロセスに対して JavaScript VM はひとつだけ、という実装もあるかもしれませんが、やはりこれもブラウザ依存なので一概には言えないかと思います。
クライアントリソースの消費について深く考えることはそれ程無いと思いますが、これを機に見直してみることも良いかと思います。
全体的にこの記事にはあまり同意できませんでした。
ひとつは、なんらかの JavaScript 処理系の特定の実装の挙動を見て、「JavaScript はこうだ」と思い込まれていること。これが「IE の JavaScript は」というような具体的な処理系が書かれていたなら、なるほどな、という良記事になったはずです。
次は、具体的にクロージャの使用を避ける事でどれだけメモリ使用量が削減できた、ということを検証した数字を挙げていないこと。そりゃ、クロージャを使用するコードと使用しないコードでは、使用しないコードのほうがメモリ使用量が少ないことは誰だって想像に難しくありません。JavaScript ではグローバルスコープを汚染しないために、即時関数式を用いる慣習がありますが、それだってメモリの無駄ということになりかねません。この記事では「クロージャを使うことでこんなにもメモリ使用量が増えるんだ、なら極力使わないようにしよう」という風には残念ながら思えませんでした。
また、「[JavaScript]メモリの浪費を避けるコーディング」というタイトルであるにもかかわらず、クロージャを使用しないとか、循環参照に気をつけるとか、そういう小手先の話しか取り上げていないことです。例えば、無駄な .js を読み込まないとか、jQuery の代わりに xxx を使うとか、そういう対処のほうがはるかにメモリ使用量削減には効率的だと思います。
最後に、書かれた方自身、この記事の内容をあまり気に留められていないことでしょうか。これを機に御社のウェブサイトを見なおしてみると良いかと思います。Google Analytics のコードが無駄に 2 度読み込まれていますよ。