株式会社クリアコード > ククログ

ククログ


Firefoxのメモリ消費の状況を定期的に監視する

概要

アドオンを使ってFirefoxのメモリ消費の詳細な情報をモニタリングし、問題の原因を究明・分析する方法と、その事例をご紹介します。

about:memoryによるメモリ消費状況の分析

Firefoxの運用において、時間と共にメモリの消費量が増加し続けるという、いわゆるメモリリークの問題に遭遇する事があります。

こういった問題の原因調査にはFirefoxのメモリの使用状況の内訳を詳しく表示できる「about:memory」が有用です。 ロケーションバーに「about:memory」と入力してEnterし、ページを開いた状態で「Measure」というボタンを押すと、その瞬間のメモリの使用状況の内訳が分析され、結果がツリー表示されます。 この結果を見れば、どのタブやどのアドオンがメモリを大量に消費しているのかについて、あたりをつける手がかりを得る事ができます。

about:memoryが役に立たないケース

しかしながら、about:memoryはページを読み込んだその瞬間の情報をスナップショットとして表示するだけの物なので、状況によっては原因の分析にあまり役立たない場合もあります。

例えば、動画再生などの「一時的に大きなデータをメモリ上に読み込むが、メモリリークはしていない」という処理と、「1回ごとの処理のメモリ消費は小さいが、解放されずにどんどん消費が積み重なっていく」という処理とがある場合には、ある瞬間のスナップショットだけを見ても、どのメモリ消費がどちらの処理に由来するものなのかを判断するのは困難です。

また、普段の利用の中で急に問題が起こってメモリ不足に陥り、最悪の場合はクラッシュに至ってしまうというようなケースだと、「では、クラッシュする直前でのabout:memoryの結果を出力して分析してみよう」などという悠長な事は言っていられません。

ましてや、開発者自身の環境では問題が再現しないという場合には、技術的に詳しくないユーザに「これこれこういう方法で情報を収集して下さい」と伝えても、期待したような情報を得られるかは疑わしい所でしょう。

about:memoryの結果を自動的に保存する

このようなケースにおいて、メモリ消費が増大していく様子をモニタリングするためのアドオンとして、Periodic Memory Usage Dumperを作成しました。

このアドオンの導入後は、「3分以上アイドル状態が続いた場合に」「5分おきにabout:memoryの情報をダンプ出力してタイムスタンプ付きで保存する」ようになります。 ファイルの保存先や、アイドル状態と判定する待ち時間、アイドル状態における定期的な出力の間隔などは、設定から変更する事もできます。

PCの性能にもよりますが、メモリ消費状況の分析は数秒以上の時間を要する場合があるため、文字入力やWebブラウズの最中に処理が走るといわゆる「プチフリーズ」が発生したように見える事になります。 そのため、このアドオンはPCがユーザがPCを一定時間以上操作していないアイドル状態の時にのみ動作するようになっています。 調整次第では、休憩のため離席している時にのみ動作するというような設定も可能です。

ダンプファイルの読み方

Periodic Memory Usage Dumperが動作している環境では、ユーザープロファイル内の「memory-usage-dumps」フォルダ、または指定した任意のフォルダ内に「2015-10-20T05-10-12.123Z.json.gz」といった名前でダンプファイルが保存されます。 (設定ダイアログと実際に出力されたダンプファイルの様子) ファイル名に含まれる日付と時刻は現地時間ではなくUTCである事に注意して下さい。

ダンプファイルの内容は、about:memoryで閲覧する事ができます。 (about:memoryの画面) about:memoryを開いてページ左上部分の「Load...」ボタンをクリックするとファイル選択のダイアログが開かれますが、ここで先のダンプファイルを選択すると内容が読み込まれ、通常のabout:memoryでの分析結果と同じ要領で表示されます。

また、「Load and diff...」ボタンをクリックしてダンプファイルを2つ選択すると、その2つの間で変化があった部分の差分が表示されます。 これにより、以下のような分析を容易に行えます。

  • 常時大量のメモリを消費している部分を無視して、一定時間内でメモリ消費量が急増した部分を見付ける。
  • 3つ以上のダンプファイルを比較して、コンスタントにメモリ消費量が増加している(メモリリークしている)部分を見付ける。

なお、メモリ消費の情報はFirefoxの設計上で明示的に分析対象とされている部分についてのみ分析され、それ以外の部分で消費されているメモリの消費量は「heap-unclassified」という部分にまとめられることになります。 このような、どのモジュールで消費されているのかの詳細が分からない部分はダークマターと呼ばれ、Firefoxのバージョンが新しいほど、モジュールごとのメモリ消費量がより詳細に分析されるようになっていてダークマターは縮小する傾向にあります。 新しいバージョンのFirefoxでもメモリリークの問題が再現するようであれば、なるべく新しいFirefoxでダンプファイルを収集するのがお薦めです。

実際の障害対応の例

実際のお客様環境での事例として、Firefoxの使用中にPCの動作が異常に遅くなったり、離席状態から戻ったらFirefoxが強制終了されてしまっていたり、というトラブルに見舞われているケースがありました。

  • そこで、実際に問題が起こっている環境においてPeriodic Memory Usage Dumperで収集したダンプファイルを分析した結果、業務上の必要から常時表示しているWebページでのメモリ消費量が何らかのきっかけで線形増加するようになる状況が発生している事が分かりました。
  • PCの動作が遅くなるのはメモリ消費量が異常に増大した結果として仮想メモリのスワップが頻発するようになるせい、Firefoxが強制終了されるのはFirefoxのプロセスが使用できるメモリを使い尽くしてWindowsにより強制終了されるせいだと推測されました。
  • その事例では、問題のWebページを再読み込みすれば消費されていたメモリが一気に解放される事を確認できました。
  • また、Webページの設計上、不意に再読み込みされても利用に問題がない事も確認できました。

そこで、そのお客様向けには、ユーザが離席している間(アイドル状態の間)に当該Webページを開いているタブを強制的に再読み込みするという対策を取るため、Reload on Idleというアドオンを作成し提供する事にしました。

Reload on Idleは、以下の特徴を持っています。

  • 自動再読み込みの対象にするWebページを、URLの正規表現で指定できる。
  • 自動再読み込みを開始するまでのアイドル時間、および、アイドル時間中の自動再読み込みの間隔を指定できる。
  • Webページによっては、再読み込みの際に「このページから移動しますか? 入力したデータは保存されません。」という確認が表示され再読み込みの操作がブロックされる場合があるが、この確認をスキップして強制的に再読み込みする。

根本的な原因(メモリリークの原因となっているWebページ内に埋め込まれているスクリプトやFlashオブジェクトの問題)の解消とはなりませんでしたが、この対策の結果、お客様環境での問題の発生頻度が下がり、実用上問題ない状態になった模様です。

まとめ

メモリ消費量の詳細な情報を定期的に収集するアドオンPeriodic Memory Usage Dumperの使い方を紹介しました。

また、このアドオンを使用した障害対応の事例と、Reload on Idleを使った回避策についても紹介しました。

クリアコードではFirefoxやThunderbirdなどのMozilla製品の技術サポート事業として、障害の原因調査や対策のご提案を有償にて行っております。 また、その過程で必要が生じた場合には、アドオンなどのソフトウェアを随時開発して提供、および(可能な場合は)フリーソフトウェアとして公開しております。 FirefoxやThunderbirdの使用や利用でお困りの際は、お問い合わせの受け付けフォームよりご相談下さい。

タグ: Mozilla
2015-10-23

«前の記事: Firefox用アドオンの署名義務化に伴う、一部アドオンのMozilla Add-ons掲載取りやめについて 最新記事 次の記事: Firefoxの独自ビルドにおける、より高度なノーブランド化の手順»
タグ:
年・日ごとに見る
2008|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|