記事内にはプロモーションが含まれています

【PHP】メモリ使用量を確認・監視する方法!最大値の取得や上限設定の変更

【PHP】メモリ使用量を確認・監視する方法!最大値の取得や上限設定の変更 PHP

PHPで大規模なデータを処理したり、長時間稼働するバッチ処理を作成したりしていると、「Fatal error: Allowed memory size of…」というメモリ不足のエラーに遭遇することがあります。

アプリケーションのパフォーマンスを維持し、予期せぬエラーを防ぐためには、スクリプトが現在どれくらいのメモリを消費しているかを正しく把握することが不可欠です。

この記事では、PHPで現在のメモリ使用量やピーク時の使用量を確認するための基本関数 memory_get_usage の使い方から、人間が見やすい単位(MBやKB)への変換方法、そしてメモリ上限(memory_limit)の確認・変更方法までを最新環境に合わせて詳しく解説します。

【本記事の信頼性】
プロフィール
執筆者:マヒロ
  • 執筆者は元エンジニア
  • SES⇒大手の社内SE⇒独立
  • 現在はこじんまりとしたプログラミングスクールを運営
  • モットーは「利他の精神」

現在のメモリ使用量を確認する memory_get_usage

PHPスクリプト実行中の「その時点での」メモリ消費量を知るには、組み込み関数である memory_get_usage() を使用します。

この関数は、スクリプトに割り当てられたメモリ量を「バイト単位(int)」で返します。

基本的な使い方とリアルメモリの確認

memory_get_usage() は引数なしで実行すると、PHPのメモリ管理システムが使用しているメモリ量を返します。

一方、引数に true を渡すと、システム(OS)から実際に割り当てられている総メモリ量を取得できます。

<?php
// 配列を作る前のメモリ使用量
echo "初期状態: " . number_format(memory_get_usage()) . " bytes\n";

// 巨大な配列を作成してメモリを消費させる
$array = range(1, 100000);

// 配列作成後のメモリ使用量
echo "配列作成後: " . number_format(memory_get_usage()) . " bytes\n";

// システムから割り当てられたリアルメモリ量
echo "リアルメモリ: " . number_format(memory_get_usage(true)) . " bytes\n";
?>

実行結果

初期状態: 398,480 bytes
配列作成後: 2,498,600 bytes
リアルメモリ: 4,194,304 bytes

number_format() 関数を使って、数値を3桁区切りのカンマ付きで見やすく整形しています。

range(1, 100000) で10万個の要素を持つ配列を作成したことで、メモリ使用量が大幅に増加しているのが分かります。

第3の出力である memory_get_usage(true) は、PHPがOSから確保しているメモリの総量です。

実際に使用している量よりも大きくなる傾向があり、サーバーのリソース設計をする際はこちらの値も参考になります。

メモリ使用量の最大値(ピーク)を確認する memory_get_peak_usage

スクリプトの開始から終了までの間で、「一瞬でも記録した最大のメモリ使用量」を知りたい場合は memory_get_peak_usage() を使います。

メモリ不足エラーは、平均使用量ではなく「最大瞬間風速」的な使用量が上限を超えた時に発生するため、この値の監視は非常に重要です。

ピーク時のメモリ量を取得するサンプル

<?php
// 処理開始
$data = [];

// メモリを大量に消費する処理
for ($i = 0; $i < 50000; $i++) {
    $data[] = md5($i);
}

// データを削除してメモリを解放
unset($data);

// 現在のメモリ使用量
echo "現在: " . number_format(memory_get_usage()) . " bytes\n";

// 実行中の最大メモリ使用量(ピーク)
echo "ピーク: " . number_format(memory_get_peak_usage()) . " bytes\n";
?>

実行結果

現在: 398,920 bytes
ピーク: 6,698,440 bytes

ループ処理の中で配列 $data にデータを詰め込んだ後、unset() で変数を破棄しています。

そのため、memory_get_usage() で取得できる「現在のメモリ使用量」は少なくなっていますが、memory_get_peak_usage() は、配列が最も大きかった時のメモリ量を記録しています。

メモリリークの調査や、バッチ処理のチューニングを行う際は、このピーク値をチェックしましょう。

メモリ使用量を「MB」や「KB」で見やすく表示する関数

memory_get_usage() が返す値は「バイト(byte)」単位です。

しかし、桁数が多くなりがちで、パッと見て「何MBなのか」が分かりにくいですよね。

そこで、バイト数を自動的に KB, MB, GB などの適切な単位に変換して表示する関数を作成して活用しましょう。

単位変換用フォーマット関数の実装例

<?php
/**
 * バイト数を適切な単位(B, KB, MB, GB)に変換する関数
 * @param int $bytes バイト数
 * @param int $precision 小数点以下の桁数
 * @return string 単位付きの文字列
 */
function formatBytes($bytes, $precision = 2) {
    $units = ['B', 'KB', 'MB', 'GB', 'TB'];
    
    // バイト数が0以下の場合はそのまま返す
    if ($bytes <= 0) {
        return '0 B';
    }

    // 1024の何乗かを計算(底を1024とした対数)
    $pow = floor(log($bytes) / log(1024));
    
    // 単位を取得
    $unit = isset($units[$pow]) ? $units[$pow] : 'TB';

    // バイト数を単位に合わせて計算
    $bytes /= (1 << (10 * $pow));

    return round($bytes, $precision) . ' ' . $unit;
}

// 使用例
echo "現在の使用量: " . formatBytes(memory_get_usage()) . "\n";
echo "ピーク使用量: " . formatBytes(memory_get_peak_usage()) . "\n";
?>

実行結果

現在の使用量: 389.5 KB
ピーク使用量: 389.5 KB

log() 関数を使って、バイト数が1024の何乗に相当するかを計算し、配列 $units から適切な単位(KBやMBなど)を選択しています。

1 << (10 * $pow) はビットシフト演算を使って $1024^{pow}$ を計算しており、これによりバイト数を単位に合わせた数値に変換します。

この関数を共通ライブラリとして持っておくと、ログ出力やデバッグ時に非常に役立ちます。

メモリ上限(memory_limit)の確認と変更方法

PHPには、1回のスクリプト実行で消費できるメモリの上限が設定されています。
これを超えると Fatal Error となり処理が停止します。

現在の上限値を確認する方法と、必要に応じて一時的に上限を引き上げる方法を見ていきましょう。

現在の memory_limit を確認する

設定ファイル php.ini に記述されている上限値は ini_get() 関数で取得できます。

<?php
echo "現在のメモリ上限: " . ini_get('memory_limit');
?>

実行結果

現在のメモリ上限: 128M

多くの環境ではデフォルトで 128M(128メガバイト)などに設定されています。

-1 と表示される場合は、メモリ無制限(上限なし)の設定です。

スクリプト内で一時的にメモリ上限を変更する

「この重いバッチ処理だけはメモリを多く使いたい」という場合は、ini_set() を使ってスクリプト実行中のみ設定を上書きできます。

<?php
// メモリ上限を 512MB に変更
ini_set('memory_limit', '512M');

// 無制限にする場合(推奨されませんが、必要な場合のみ)
// ini_set('memory_limit', '-1');

echo "変更後のメモリ上限: " . ini_get('memory_limit');
?>

ini_set('memory_limit', '512M') を実行することで、このスクリプトが終了するまでの間、メモリ上限が512MBに拡張されます。

ただし、レンタルサーバーなどの環境によっては、php.ini.htaccess 以外での変更が許可されていない(ini_set が無効化されている)場合もあるため注意が必要です。

PHPのメモリ使用量を減らすためのポイント

メモリ使用量をただ確認するだけでなく、消費量を抑えるコーディングを意識することも大切です。

最後に、メモリを節約するための代表的なテクニックをいくつか紹介します。

不要になった変数は unset で破棄する

使い終わった巨大な配列やオブジェクトは、unset($variable) で明示的に破棄することでメモリを解放できます。

特に長時間動くループ処理の中では効果的です。

データベースの取得結果を一度にすべて読み込まない

データベースから大量のデータを取得する際、fetchAll() などで全件を配列に入れるとメモリを圧迫します。

代わりに fetch() を使って1行ずつ処理するか、Laravelなどのフレームワークであれば cursor()chunk() メソッドを活用して、少しずつデータをメモリに乗せるようにしましょう。

ジェネレータ(Generator)を活用する

配列の代わりに yield を使用したジェネレータを使うと、すべての要素をメモリに保持せずにループ処理を行えるため、メモリ消費量を劇的に削減できます。

PHPのスキルを活かして年収を上げる方法

以上、PHPでメモリ使用量を確認・監視する方法について解説してきました。

なお、PHPのスキルがある場合には、「転職して年収をアップさせる」「副業で稼ぐ」といった方法を検討するのがおすすめです。

PHPエンジニアの需要は非常に高く求人数・案件数も多いため、転職によって数十万円の年収アップはザラで、100万円以上年収が上がることも珍しくありません。

なお、転職によって年収を上げたい場合は、エンジニア専門の転職エージェントサービスを利用するのが最適です。

今すぐ転職する気がなくとも、とりあえず転職エージェントに無料登録しておくだけで、スカウトが届いたり、思わぬ好待遇の求人情報が送られてきたりするというメリットがあります。

併せて、副業案件を獲得できるエージェントにも登録しておくと、空いている時間を活かして稼げるようなPHPの案件を探しやすくなります。

転職エージェントも副業エージェントも、登録・利用は完全無料なので、どんな求人や副業案件があるのか気になる方は、気軽に利用してみるとよいでしょう。