稼働中の PHP プロセスが何にメモリを消費しているかを突き止めるには、OpenResty XRay でプロファイリングします。変更していないプロセスにアタッチし、生きている PHP オブジェクトを保持しているメモリ量で順位付けし、最大のオブジェクトをデータ参照パスによって正確なソース行まで追跡します。コードの変更も再起動も不要です。

本チュートリアルでは、OpenResty XRay のガイド分析と、弊社が独自に開発した PHP オブジェクトメモリ分布フレームグラフを使って、この流れを解説します。実例として、controller が保持する単一の 40MB の HTML 文字列が原因となったケースを扱います。

症状: PHP プロセスが top で大量のメモリを消費

まず、top コマンドを実行してメモリ使用量を確認します。ご覧のように、この php プロセスが最も多くのメモリを消費しており、RSS が 37MB を超えています。

top の出力。php プロセスが最も多くのメモリ(37MB 超の RSS)を消費している様子

ps コマンドを実行して、このプロセスの詳細を確認しましょう。このプロセスが使用している PHP バイナリ実行ファイルは、Linux ディストリビューションに同梱される標準のものです。

ps の出力。プロセスが標準の /usr/bin/php バイナリであることを示している

OpenResty XRay を使用して、この変更していないプロセスを検査できます。リアルタイムで分析を行い、メモリが具体的にどこで消費されているかを特定します。

OpenResty XRay のガイド分析による最大の PHP オブジェクトの特定

ブラウザで OpenResty XRay の Web コンソールを開き、分析対象のマシンが正しいことを確認します。「Guided Analysis」ページに移動すると、OpenResty XRay が診断できる問題の種類を選べます。

OpenResty XRay のガイド分析の問題タイプ。High memory usage が含まれている

「High memory usage」を選択し、先ほどの PHP アプリケーションと top で判明したプロセス(RSS が 35MB を超えているもの)を選び、PHP と C/C++ の両方の言語レベルを選択したまま分析を開始します。1〜2 ラウンドの分析の後、OpenResty XRay が自動的にレポートを生成します。PHP-Land の下に、最も多くのメモリを占有している PHP メモリオブジェクトの参照パスが表示されます。

OpenResty XRay レポートで第 1 位となった、最もホットな PHP GC オブジェクトのメモリ分布参照パス

ご覧のように、Web ページの HTML ソース文字列が約 40MB のメモリを占有しています。

約 40MB のメモリを占有する Web ページの HTML ソース文字列

productPagecontroller のプロパティで、この文字列を格納しています。

この 40MB の HTML 文字列を格納している controller の productPage プロパティ

Illuminate\Routing\Route クラスの主な機能は、URL リクエストを controller メソッドにマッピングすることです。

URL リクエストを controller メソッドにマッピングする Illuminate Routing Route クラス

このデータ参照パスは、下の PHP 言語レベルの GC オブジェクトメモリ分布フレームグラフから自動的に導出されたものです。

PHP-Land の PHP GC オブジェクトメモリ分布フレームグラフ。40MB の文字列まで至る最もホットなバックトレースを強調表示している

最大のオブジェクトのソース行までの追跡

参照パスから productPage プロパティをコピーし、PHP アプリケーションのソースコードディレクトリに移動して、productPage 変数識別子を含むファイルを grep で検索します。

grep でソースディレクトリから productPage 変数識別子を検索している様子

これは代入文のソースコードの行番号――ProdController.php の 40 行目――です。

grep の出力。productPage の代入文が ProdController.php の 40 行目にあることを示している

エディタでソースファイルを開きます。ここがプロパティを定義している箇所です。

ProdController.php のソースファイルで productPage プロパティを定義している箇所

40 行目に移動します。$this->productPage = file_get_contents($file_path) という文が、ページ全体を一度にメモリへ読み込んでおり、これが大きなメモリオブジェクトを生成しています。ストリーミングレスポンスを使用してメモリ使用を最適化することをお勧めします。

ProdController.php の 40 行目。file_get_contents でファイル全体を productPage に代入している

Insights レポートによる PHP プロセスメモリの自動監視

OpenResty XRay は、稼働中のプロセスを自動的に監視し、分析レポートを表示することもできます。「Insights」ページでは日次および週次のレポートを確認できるため、ガイド分析を手動で実行する必要はありません。ただし、「Guided Analysis」はアプリケーションの開発やデモンストレーションには依然として有用です。

OpenResty XRay の Insights における、この PHP アプリケーションの日次メモリレポート

よくある質問

どの PHP プロセスが最もメモリを消費しているかを特定するには?

top コマンドを実行すると、php プロセスが最もメモリを消費しているものとして表示されます。本例では 37MB を超えています。ps を実行すると詳細を確認でき、ここでは Linux ディストリビューションに同梱される標準 PHP バイナリであることがわかります。その後、OpenResty XRay がまさにそのプロセスを分析し、メモリがどこで消費されているかを突き止めます。

コードを変更したり再起動したりせずに PHP のメモリ使用量をプロファイリングできますか?

はい。OpenResty XRay は、変更していない稼働中の PHP プロセスをリアルタイムで分析します――本例では Linux ディストリビューションに同梱される標準 PHP バイナリです。プロセスをそのままの状態で扱うため、アプリケーションを変更したり再起動したりせずに、メモリの行き先を確認できます。

PHP メモリオブジェクトの参照パスとは何ですか?

最も多くのメモリを保持しているオブジェクトへの参照パスのことです。本例では、controllerproductPage プロパティに格納された約 40MB の HTML 文字列と、リクエストをその controller にマッピングする Route クラスがそれにあたります。OpenResty XRay は、PHP 言語レベルの GC オブジェクトメモリ分布フレームグラフからこのパスを自動的に導出します。

大きな PHP オブジェクトによる高メモリ使用を減らすには?

最大のオブジェクトを、それを生成しているソース行まで追跡します――本例では、productPage プロパティに代入して大きなメモリオブジェクトを生成している文です。OpenResty XRay のレポートは、メモリ使用を最適化するためにストリーミングレスポンスを使用することを推奨しています。

OpenResty XRay について

OpenResty XRay動的トレーシング製品であり、実行中のアプリケーションを自動的に分析して、パフォーマンスの問題、動作の問題、セキュリティの脆弱性のトラブルシューティングを行い、実行可能な提案を提供します。基盤となる実装において、OpenResty XRay は弊社の Y 言語によって駆動され、Stap+、eBPF+、GDB、ODB など、様々な環境下で複数の異なるランタイムをサポートします。

著者について

章亦春(Zhang Yichun)は、オープンソースの OpenResty® プロジェクトの創始者であり、OpenResty Inc. の CEO および創業者です。

章亦春(GitHub ID: agentzh)は中国江蘇省生まれで、現在は米国ベイエリアに在住しております。彼は中国における初期のオープンソース技術と文化の提唱者およびリーダーの一人であり、Cloudflare、Yahoo!、Alibaba など、国際的に有名なハイテク企業に勤務した経験があります。「エッジコンピューティング」、「動的トレーシング」、「機械プログラミング」 の先駆者であり、22 年以上のプログラミング経験と 16 年以上のオープンソース経験を持っております。世界中で 4000 万以上のドメイン名を持つユーザーを抱えるオープンソースプロジェクトのリーダーとして、彼は OpenResty® オープンソースプロジェクトをベースに、米国シリコンバレーの中心部にハイテク企業 OpenResty Inc. を設立いたしました。同社の主力製品である OpenResty XRay動的トレーシング技術を利用した非侵入型の障害分析および排除ツール)と OpenResty Edge(マイクロサービスおよび分散トラフィックに最適化された多機能ゲートウェイソフトウェア)は、世界中の多くの上場企業および大企業から高い評価を得ております。OpenResty 以外にも、章亦春は Linux カーネル、Nginx、LuaJITGDBSystemTapLLVM、Perl など、複数のオープンソースプロジェクトに累計 100 万行以上のコードを寄与し、60 以上のオープンソースソフトウェアライブラリを執筆しております。

翻訳

英語版の原文と日本語訳版(本文)をご用意しております。読者の皆様による他の言語への翻訳版も歓迎いたします。全文翻訳で省略がなければ、採用を検討させていただきます。心より感謝申し上げます!