JSerでも何となく知っておいた方が良さそうな気がしたGCについて

最近、知り合いに「アレって酔って書いてんの?」と言われましたが、シラフです。もし仮に、いつもより若干テンションが高いように感じられるとしたら、今飲んでる麦茶に誰かが白い粉末状の非合法な何かを混ぜたんだと思います。ということで、こんばんは。

突然ですが、あなたは人知れず暗躍するプログラミング界のアサシン、ガベージコレクター(通称:GC)と呼ばれる存在をご存知だろうか。なんだこいつそんなこともしらねーの、と思った方は、その言の葉の刃を、キーボードの⌘+Wに向けて解き放ち、このしょうもない文書と出会ってしまった運命に終止符を打っていただきたい。ぜひとも。

ガベージコレクターは、機能的にはガベージコレクションと呼ばれるものを司る、なんかかっこいいやつです。ガベージコレクションが何かと言えば、例えばJavaScriptが実行された時、文字列が定義されればStringオブジェクトがメモリ上に乗っかるわけですが、これがずっと放置されたままだと、いつかメモリが一杯になってしまいます。
そこで、ガベージコレクタは、参照のなくなったオブジェクトを探し出して、それを排除して記録領域を確保します。利用価値のなくなったオブジェクトは、みんなガベージコレクタに殺されてしまいます。これって厨二心をくすぐられませんか。もうなんていうか、エクスキューショナーですよ。誰か「なれる!GC」とか書きませんか。

ガベージコレクションがない言語というのは、自前でメモリ管理をするわけですが、JavaScriptはその辺を自動で全部いい感じにやってもらえるので、とても楽ができます。その反面、ガベージコレクターは結構頑張っていて、やつらが仕事をする時というのは、プログラムの実行がブロックされてしまうので、大漁にオブジェクトを作ったり使わなくなったりすると、結果として例えばアニメーションやWebアプリケーションの実行なんかがカクカクとしてしまう場合があります。

それを避ける為の手法として、オブジェクトプールなんていう考え方が有効な場合があるようです。例えば、次々に粒子が飛んで消えていくような効果を作った時に、常に新しい粒子のclassをnewするとコストが高そうですが、消えてしまった粒子のオブジェクトをどこかに配列で貯めておいて、新しい粒子を描画する時にその配列から取り出して使い回す実装が個人的には視覚的にイメージし易いかなと思いました。
また、SPAみたいなものを作った場合なんかも、ブラウザの再読み込みによるリセットもなく大漁のオブジェクトの生成と破棄が走ってしまうので、あんまり適当にやらないで何か考えた方がいいかもしれません。

React.jsなんかも、中を少し覗いてみると react/src/shared/utils/PooledClass.js みたいな生成したclassをpoolしておく仕組みがあって、至る所で呼び出されていたりします。僕は長らくVue.jsユーザーなんですが、Vue.jsはざっと見る感じそういう仕組みが特にないので、別に致命的にまずいってことは恐らくないけど、vue-routerとかでSPA作ると時々ひっかかり感じたりするの、その辺だったりするのかな?とは思ったりしています。(全部読んでないので、見逃してるだけだったらごめんなさい)

今まで生きてきて、あんまりJavaScriptでメモリ意識することってなかったんだけど、なんかそういうのも考えないといけないのかなという気がした、わんわんなのでした。