Firefoxのバグ、9分おきにフリーズする件について
何だか気になるので調査
リンクを辿って、
に行く。
何が気になるのか
- どんな処理を行ったときにFirefoxがフリーズするほどの処理が走るのか
- 対象ユーザはどんな人か
- 何故9分おきなのか
- 対応策のアドオンは何をやっているのか
- 効果はあるのか
どんなバグか
『nsNavHistory::AsyncExecuteLegacyQueries
メソッドがSQLのステートメントを作るのに同期的なcreateStatement
を使用しているのでメインスレッドがそこでブロックされる。替わりに、createAsyncStatement
を使用すべき。』というもの。
どんな変更が入っている?
テストコードを除くと、主に2つファイル
- nsCookieService.cpp
- nsNavHistory.cpp
この2つのファイル内のdbConn-<CreateStatement
がdbConn-<CreaateAsyncStatement
に変更されている。
変更箇所はどんな処理部分?
nsCookieService
こちらはCookieの管理を行うサービス
- nsCookieService::RemoveAll()
- 保管されているCookieを全削除(
DELETE FROM moz_cookies
) - 全削除を呼び出すのは稀。今回の件とは別だけど、ついでにって感じだろう
- 保管されているCookieを全削除(
- nsCookieService::Read()
nsNavHistory
こちらはPlacesと呼ばれるブックマークと履歴の管理を行うサービス。
- nsNavHistory::AsyncExecuteLegacyQueries()
- 複数のクエリを非同期実行するメソッドのはずだが...同期的実行になってしまっていた模様
- 実行する頻度によってはボトルネックになりそう
- nsNavHistory::BindQueryClauseParameters()
- nsNavHistory::FixInvalidFrecencies()
- frecencyとやらの値が0未満のデータに対して変更(
UPDATE moz_places SET frecency = CALCULATE_FRECENCY(id) WHERE frecency > 0
) - これも実行頻度によってはボトルネックになると思われる
- frecencyとやらの値が0未満のデータに対して変更(
小まとめ
問題は以下2点のメソッドと思われる。
- nsNavHistory::AsyncExecuteLegacyQueries
- nsNavHistory::FixInvalidFrecencies
nsNavHistory::AsyncExecuteLegacyQueries
これは何処から呼ばれているか。Mozilla Cross-Referenceで検索する。
テストコードとIDLを除くと、呼び出しているのは一つのみ
名前から察するに、Windows7のジャンプリストのことだろう、という予想通りWindows7でないと動かない仕組みになっている。
どの程度の頻度で呼び出されるか
WindowsJumpList.jsmを読むと、
_updateTimer
メソッドを実行して- nsITimerにより定期的に
notify
メソッドを呼び出している- 頻度:
browser.taskbar.lists.refreshInSeconds
(デフォルト: 120) 秒 - いくつか条件をクリア(Firefox起動中は大抵通りそうな条件)
_buildList
メソッド呼び出しbrowser.taskbar.lists.frequent.enabled
(デフォルト: true)がtrue
なら、--中略--_getHistoryResults
呼び出しbrowser.taskbar.lists.recent.enabled
(デフォルト: false)がtrue
なら、--中略--_getHistoryResults
呼び出し
- 頻度:
問題のasyncExecuteLegacyQueries
は_getHistoryResults
から呼び出されている。
まあだいたい120秒間隔で同期的SQLが実行されていることになるのだろう。
_getHistoryResults
PlacesQueryなるものを作成して履歴を照会している。
それぞれ、デフォルト値なら、
- Frequent(よく行くページ):
place:sort=8&redirectsMode=2&maxResults=7
- Recent(最近行ったページ):
place:sort=4&redirectsMode=2&maxResults=14
となる。(このコードをURLとしてブックマークすると特殊なフォルダとして使えるようになるよ)
どちらも訪問回数や訪問時刻でソートするし、訪問回数なら集約関数とかgroup by
を使うことになるしで多少重たい処理かも。
まあ詳しくは本を買えw

Firefox 3 Hacks ―Mozillaテクノロジ徹底活用テクニック
- 作者: 江村秀之,池田譲治,下田洋志,松澤太郎,dynamis
- 出版社/メーカー: オライリージャパン
- 発売日: 2008/08/27
- メディア: 単行本(ソフトカバー)
- 購入: 4人 クリック: 489回
- この商品を含むブログ (54件) を見る
小まとめ
- Windows 7限定
- それなりの頻度で定期的に実行され、その間メインスレッドがブロックされると思われる
- デフォルト120秒間隔なので「9分間隔」で、という理由にはなっていない気がする
- 本を買え
nsNavHistory::FixInvalidFrecencies
次、nsNavHistory::FixInvalidFrecencies
。
これが呼ばれるのは、結局のところ、オブザーバーのaTopicがidle-daily
の場合になる。名前のとおり、少なくとも24時間毎の実行になるため、「9分毎」はあり得ないだろう。
ということで、実行頻度は低い。
対応策のアドオン
Firefoxにバグ、9分おきにフリーズ | エンタープライズ | マイコミジャーナル
- 「Places Maintenance add-on」をインストール。
- 「Places Maintenance」のオプションダイアログを起動。
- 「Expire」を選択し「Execute」をクリック。
- 「Places Maintenance」アドオンをアンインストール。もちろん必要であればインストールしておいても問題ない。
アドオンの中身を見てみると、結局のところ、PlacesDBUtils.expire
を実行しているようだ。
PlacesDBUtils.expire
- 訪問7日間より前の履歴データを削除
- 履歴とブックマークのテーブルから参照されていないエントリを削除
- 参照されないアイコンデータの削除
- 参照されないアノテーションの削除
- 期限切れのアノテーションの削除
- 参照されない入力履歴の削除
- 各テーブルの統計情報を取得
と、要はデータの削除を行っている。
データ量が減って照会が速くなるぞ、ワーイってわけ。
エラーコンソールを起動して
Components.utils.import("resource://gre/modules/PlacesDBUtils.jsm").PlacesDBUtils.expire()
と実行すれば、アドオン入れなくてもOKかもw
Places DBのメンテ
コードを読んでいて気付いたのだが、DBのメンテナンスが通常だと、places.history.expiration.interval_seconds
(設定されていない場合は 180) x 3秒、通常設定されていないので、9分間隔で動くのよね。
PlacesDBUtils.expire
からと比べると量は少ないはずだけど、削除処理は走る。非同期処理のはずだけれどDBが大きい場合は馬鹿にならない処理となりそう。これ、結構怪しい。
と思いながら、Bugzillaの方を読み直すと(面倒臭がって初めは読んでなかった)、こちらの問題っぽいコメントが出ていた。予備知識をもって読むと理解度が全然違うね!
というわけで、
To fix the hangs we'll also need bug 690354 and bug 691509 though.
https://bugzilla.mozilla.org/show_bug.cgi?id=686025#c115
というコメントが付いているわけですね。
結論
- 今回のBug 686025のバグフィックスだけでは不十分
- Windows 7ユーザは多少重たさが解消されるかも
- places.sqlite 周りの定期メンテナンスが適切に行われないとフリーズする可能性はまだある
どんな処理を行った時に重たくなるか
- 9分間隔くらいで動くplaces.sqliteのメンテナンス
- 期限切れデータの削除
- 統計情報取得
何故9分おきか
- places.sqliteのメンテナンスが走る間隔だから
対応策のアドオンは何をやっているか
- 強烈なメンテナンス(7日間より前のデータは全削除)
- 効果はある(作った人、Marco Bonardo が今回のパッチを作っている)
って感じでしょうか。
ふぅ〜疲れた。おやすみ!
:wq