たくさんタブを開く人にとってFirefox 5は福音となったか

 3ヶ月ほど前に、たくさんタブを開く人にとってFirefox 5は福音となる…かも という記事を書いた。
 6/21にFirefox 5がリリースされ、実際にFirefox 5が使えるようになった。確かに、Firefox 5になってから、CPU使用率は下がったようだ。タブを100個以上開いた場合でも、CPU使用率は5%程度にまで下がっている。そういう意味では恩恵は大きい。
 ここで話が終わればいいのだが、今度は数秒に1度のCPU使用率のスパイクが気になるようになってきた。環境によってスパイクぶりは違ってくるのだが、会社のFirefoxだと、CPU使用率が80%程度にまで一瞬だけ上がる。しかも、そのたびにブラウザが固まる。最近は会社だと暑くて数秒に1回ファンがうるさく回るので、Firefoxを使えなくなってしまった。
 数秒に一度のCPU使用率の上昇というと、まず疑うべきはGCだろう。「firefox garbage collector」でぐぐると、Firefox unresponsive when garbage collector is workingというバグ報告が見つかった。他にも同じような症状で困っている人はいるらしい。
 結局、このバグ自体はunconfirmedで片付けられてしまっているようだが、いくつか面白い情報が手に入った。about:configで"javascript.options.mem.log"というオプションをtrueにすると、GCを起動するたびにログを吐いてくれるようになるらしい。試してみると、ブラウザが固まるタイミングとGCのタイミングは完全に一致した。
 ログを見るとGCの他にCCというものが頻繁に発生しており、これはCycle Collectorというものらしい。Firefoxは、JSオブジェクトのGCにはmark & sweepを、DOMオブジェクトのGCにはreference countを採用しており、reference countでは循環参照を回収できないので、cycle collectorで循環参照しているgarbageを回収するようだ。なぜこのような形になっているのかはちょっとよくわからない。どうせstop the worldしてしまうなら、全部mark & sweepじゃダメなのだろうか。そんなに性能差が大きいんだろうか?
 CCはcollected: 0、つまり何も回収できなかったというケースが非常に多くあるようだ。しかもGCよりもはるかに頻繁に起動されており、とてもうざったい。いろいろ操作して見ながら観察してみたところ、DOMツリーを変更しそうな操作をしない限り、CCではオブジェクトを回収できないようだ。まぁ、DOMを構成するオブジェクト(のうち、循環参照を起こしているgarbage)を回収するためのものなのだから、当たり前と言えば当たり前である。
 ある一つのDOMが確保するメモリチャンクは通常はそれほど大きくならないと思うので、CCの処理はもっと細切れにできないものだろうか、と思う。さすがにコードを読んでるほどの暇は今は残念ながらないのでそこら辺はよくわからないけど。
 パープルバッファを世代別にすることでポーズタイムを短くするという話があったりとかする。しかし、既にmark & sweepをincremental化するという計画があるのならば、そっちに乗っかるのが一番早いのではないかという気がしている。