エラーの内容
アプリがクラッシュし、ログに以下が出力されました:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 65536 bytes) in /var/www/html/app/vendor/something/heavy.php on line 342
134217728バイト = 128MB。PHPがメモリ上限に達し、それ以上の割り当てを拒否しました。プロセスは停止し、ユーザーには白いページまたは500エラーが表示されています。
素早いトリアージ
まず、PHPが実際に使用しているメモリ制限を確認します:
php -r "echo ini_get('memory_limit');"
または、ブラウザからアクセスできる一時的なPHPファイルにこれを追加します:
<?php echo ini_get('memory_limit');
128M、256M、または現在の上限値が表示されます。-1が表示された場合、メモリは無制限です — エラーは別の場所から発生しています(代わりにopen_basedirまたはOSレベルの制限を確認してください)。
また、実際に読み込まれているphp.iniを確認してください — 複数存在することがよくあります:
php --ini
PHP-FPM専用の場合:
php-fpm8.1 --ini
解決策1:php.iniで制限を増やす(恒久的な修正)
まずここから始めましょう。この変更は永続的です — 再起動後も維持され、サーバー上でPHPが実行するすべてに対してグローバルに適用されます。アクティブなphp.iniを見つけて編集します:
; memory_limitの行を見つけて変更します:
memory_limit = 512M
保存後、PHP-FPMまたはApacheを再起動します:
# PHP-FPM
sudo systemctl restart php8.1-fpm
# Apache with mod_php
sudo systemctl restart apache2
変更が反映されたことを確認します:
php -r "echo ini_get('memory_limit');"
解決策2:プロジェクトごとに設定する(php.iniを変更できない場合)
共有ホスティングやロックされたサーバーでは、php.iniにアクセスできないことがよくあります。いくつかの回避策があります:
.htaccessで設定する(Apacheのみ)
php_value memory_limit 512M
PHPスクリプト内で設定する(ファイルの先頭)
<?php
ini_set('memory_limit', '512M');
ほとんどのホストで機能します。セキュリティ上の理由からini_setを無効にしていたり、suhosinを実行してランタイムの変更をブロックしているホストもあります。どちらの方法も機能しない場合は、ホストに連絡する必要があります。
WordPress固有の設定
wp-config.phpの*/* That's all, stop editing! */*という行の前に追加します:
define('WP_MEMORY_LIMIT', '512M');
define('WP_MAX_MEMORY_LIMIT', '512M'); // 管理エリア用
解決策3:PHP-FPMプール設定
PHP-FPMを使用していますか?プール設定でphp.iniを完全に上書きできます。プールファイル(通常は/etc/php/8.1/fpm/pool.d/www.conf)を確認します:
; プール設定にこの行を追加または更新します:
php_admin_value[memory_limit] = 512M
その後、再起動します:
sudo systemctl restart php8.1-fpm
php_admin_valueディレクティブはphp.iniより優先され、アプリケーションコード内のini_set()で上書きできません — サイトごとに制限をロックしたい場合に便利です。
修正の確認
再起動が成功したと思い込まないでください。確認します:
# CLI
php -r "echo ini_get('memory_limit') . PHP_EOL;"
# Webアプリの場合、テストエンドポイントにアクセスします
curl -s https://yourapp.com/phpinfo.php | grep memory_limit
エラーログを確認して、致命的エラーが表示されなくなったことを確認します:
sudo tail -f /var/log/php8.1-fpm.log
sudo tail -f /var/log/nginx/error.log
エラーが再発した場合は?
一度制限を引き上げることは普通です。数ヶ月ごとに繰り返す場合は別の話です — コード内の何かが必要以上のデータをメモリに読み込んでいます。よくある原因:
- 大規模データセットのクエリ:数千のEloquent/Doctrineオブジェクトを一度に読み込む。チャンク処理を使用してください:
User::chunk(200, fn($users) => ...) - 画像処理:GDとImagickはメモリを大量に消費します。2000万画素の画像を処理すると300MB以上消費することがあります。処理前にリサイズするか、より高い制限を持つキューワーカーにオフロードしてください。
- Composerオートロードの肥大化:同時に読み込まれるパッケージが多すぎます。
memory_get_peak_usage(true)でプロファイリングしてください。 - 再帰関数または無限ループ:これらは静かにメモリを消費します。深さカウンターを追加するか、反復的なアプローチに切り替えてください。
簡単なメモリプロファイリング:
<?php
// コード全体にチェックポイントを追加します
echo memory_get_usage(true) / 1024 / 1024 . ' MB' . PHP_EOL;
// 最後に:
echo 'Peak: ' . memory_get_peak_usage(true) / 1024 / 1024 . ' MB' . PHP_EOL;
メモリはどれくらい設定すべきか?
使用するスタックによって異なります。実際に機能する値は以下の通りです:
- 一般的なWebアプリ:256Mが妥当
- プラグインを使用したWordPress:256M〜512M
- 重い処理を行うLaravel/Symfony:256M〜512M
- 画像処理 / データインポート:CLIワーカーには512M〜1024M
- 本番のWebプロセスには絶対に
-1を設定しない — 暴走したスクリプトがサーバーをダウンさせます
明確な制限を設定し、何か問題が起きたときにはっきりクラッシュさせましょう。見えないメモリ消費は、目に見えるエラーよりも悪い結果をもたらします。
なぜ128MBでは不十分なのか
このデフォルト値はPHP 5.2の時代に設定されたもので、当時のほとんどのアプリはいくつかのスクリプトとMySQLクエリ程度でした。状況は変わりました。いくつかの標準パッケージを含む新鮮なLaravel 11アプリは、実際のリクエストを処理する前のブートストラップだけで60〜80MBを消費することがあります。
一度制限を引き上げることは正しい判断です。しかし繰り返し引き上げている場合、アプリは不必要なデータを読み込んでいます:オブジェクトにハイドレートされたテーブル全体の結果、未使用パッケージのオートロード、キューに入れる代わりにインラインで処理される画像などです。
CLIスクリプトとキューワーカーには、専用のプールまたはスクリプトでより高い制限を設定してください。夜間のインポートジョブに対応するためにグローバルなWeb制限を膨らませないでください。

