2026年5月28日
2026年5月28日
WordPressのPHPメモリ不足エラー(Allowed memory size exhausted)の原因と直し方
WordPress で次のようなエラーが出て、画面が真っ白になったり保存できなくなったりすることがあります。
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in /var/www/html/wp-content/plugins/example-plugin/includes/class-example.php on line 120
これは、1回のリクエストで PHP が使えるメモリの上限に達したという意味です。この記事では、エラーの数値からどの上限に当たったかを読み取り、上限を正しく引き上げる手順と、メモリを多く使っている原因を探す方法を説明します。内容は 2026年10月時点の WordPress を前提にしています。
エラーの数値から、当たった上限を読み取る
「Allowed memory size of」の後の数値が、その時点の上限(バイト)です。よく見る値は次のとおりです。
| エラーの数値 | 上限 | 考えられる設定 |
|---|---|---|
| 41943040 | 40M | WordPress の WP_MEMORY_LIMIT の既定値(シングルサイト) |
| 67108864 | 64M | マルチサイトの WP_MEMORY_LIMIT の既定値、または PHP の設定 |
| 134217728 | 128M | PHP の memory_limit の既定値 |
| 268435456 | 256M | WP_MAX_MEMORY_LIMIT の既定値(管理画面など) |
エラーの最後の「in ファイル名 on line 番号」は、上限に達した瞬間に実行していた場所です。そのプラグインやテーマがメモリを多く使っている手がかりになりますが、それまでに他の処理が使った分も合計されているので、ここに出たものが原因とは限りません。
WordPress のメモリ上限の仕組み
メモリの上限は PHP の memory_limit で決まり、WordPress は起動時に次の2つの定数でこれを引き上げます(wp-includes/default-constants.php)。
| 定数 | 既定値 | 使われる場面 |
|---|---|---|
WP_MEMORY_LIMIT |
40M(マルチサイトは 64M) | すべてのリクエスト。今の memory_limit より大きいときだけ引き上げる |
WP_MAX_MEMORY_LIMIT |
256M(PHP の上限がそれより大きい場合はその値) | 管理者(manage_options 権限)が開く管理画面、画像の編集・リサイズ、WP-Cron など |
要点は次の3つです。
- WordPress は上限を下げません。PHP の
memory_limitが 128M なら、WP_MEMORY_LIMITが既定の 40M でも上限は 128M のままです。 WP_MEMORY_LIMITを PHP のmemory_limitより大きくすると、WordPress はini_set()でその値まで引き上げます。PHP の設定より大きい値でも効きます。- ただし、サーバー側で
memory_limitの変更が禁止されている場合(PHP-FPM のphp_admin_valueで固定している、ini_setを無効にしているなど)は、WordPress の定数では変わりません。その場合は PHP の設定そのものを変えます。
手順1:今の上限を確認する
管理画面の「ツール」→「サイトヘルス」→「情報」タブを開き、「サーバー」の「PHP メモリ上限」と、「WordPress 定数」の WP_MEMORY_LIMIT・WP_MAX_MEMORY_LIMIT を見ます。管理画面で上限が引き上げられている場合は、「PHPメモリ制限 (管理画面のみ)」も表示されます。
WP-CLI でも定数は確認できます。シェルでの変数展開を避けるため、PHP コードは単一引用符で囲みます。
wp eval 'echo WP_MEMORY_LIMIT, " / ", WP_MAX_MEMORY_LIMIT, PHP_EOL;'
WP-CLI はコマンドライン用の PHP(php-cli)の設定で動くため、ini_get( 'memory_limit' ) の値は Web サーバーで動く PHP(PHP-FPM など)と違うことがあります。Web 側の値はサイトヘルスで確認してください。
手順2:メモリ上限を引き上げる
wp-config.php で WordPress の上限を上げる
wp-config.php の、編集はここまでと書かれたコメント(英語版では /* That's all, stop editing! */)より前に追記します。require_once ABSPATH . 'wp-settings.php'; より後に書くと効きません。
define( 'WP_MEMORY_LIMIT', '256M' );
// 管理画面などで使う上限。既定の 256M で足りない場合だけ書く
define( 'WP_MAX_MEMORY_LIMIT', '512M' );
保存したら、サイトヘルスで値が変わったかを確認します。変わらない場合は、サーバー側で memory_limit が固定されているので、次の方法で PHP の設定を変えます。
PHP の memory_limit を上げる
環境によって設定場所が違います。
| 環境 | 設定する場所 | 書き方 |
|---|---|---|
| VPS・専用サーバー(PHP-FPM) | php.ini、または FPM のプール設定 |
memory_limit = 256M、プール設定なら php_admin_value[memory_limit] = 256M |
| PHP-FPM・CGI で動く共用サーバー | WordPress のディレクトリの .user.ini |
memory_limit = 256M |
| Apache + mod_php | .htaccess |
php_value memory_limit 256M |
| レンタルサーバー | 各社のコントロールパネルの PHP 設定 | 画面の案内に従う |
VPS などでは、読み込まれている php.ini を確認してから編集し、PHP-FPM を再起動します。
# Web 用の PHP-FPM が読む php.ini の場所(バージョンは環境に合わせる)
php-fpm8.3 -i | grep "Loaded Configuration File"
# 編集後に再起動する
sudo systemctl restart php8.3-fpm
.user.ini の変更は、PHP が一定時間ごとに読み直すため(user_ini.cache_ttl、既定は 300 秒)、反映まで最大 5 分ほどかかります。.htaccess の php_value は mod_php のときだけ使えます。PHP-FPM の環境で書くと 500 エラーになるので注意してください。
memory_limit = -1(無制限)は、1つの重いリクエストがサーバーのメモリをすべて使い切るおそれがあるため、本番環境では使わないでください。
手順3:メモリを多く使っている原因を探す
上限を上げればエラーは止まりますが、原因が特定のプラグインの不具合なら、使用量はさらに増えていきます。上げる前か後に、どこで使っているかを確認します。
プラグインを外して比べる(WP-CLI)
WP-CLI の --skip-plugins を使うと、プラグインを読み込まずに WordPress を起動できます。読み込み時のメモリを比べることで、重いプラグインの目安がつきます。
# すべてのプラグインを読み込んだとき
wp eval 'echo size_format( memory_get_peak_usage(), 1 ), PHP_EOL;'
# プラグインを読み込まないとき
wp --skip-plugins eval 'echo size_format( memory_get_peak_usage(), 1 ), PHP_EOL;'
# 特定のプラグインだけ外したとき(スラッグはカンマ区切り)
wp --skip-plugins=woocommerce eval 'echo size_format( memory_get_peak_usage(), 1 ), PHP_EOL;'
これは WordPress を起動しただけの量で、ページの表示や保存の処理で使う分は含みません。エラーが出る操作そのものを調べるには、次の方法を使います。
本番に近い環境で切り分ける
- Query Monitor プラグイン:ページごとのピークメモリ使用量と、実行されたクエリ・フックを管理画面のツールバーに表示します。エラーにならない範囲の操作で、どのページが重いかを比べられます。
- Health Check & Troubleshooting プラグイン:トラブルシューティングモードで、自分のログインセッションだけプラグインを無効にした状態にできます。訪問者の表示を変えずに、1つずつ有効にして再現するかを確かめられます。
- ステージング環境:本番を複製した環境で、プラグインを1つずつ無効にして再現を確かめます。
メモリを多く使ったリクエストを記録する
どの URL でメモリを多く使っているかを記録するには、次のファイルを wp-content/mu-plugins/memory-peak-logger.php として置きます(mu-plugins フォルダーが無ければ作ります)。上限の 80% を超えたリクエストだけを、PHP のエラーログ(WP_DEBUG_LOG を有効にしていれば wp-content/debug.log)に書きます。
<?php
/**
* Plugin Name: Memory peak logger(調査が終わったら削除する)
*/
add_action( 'shutdown', function () {
$limit = wp_convert_hr_to_bytes( ini_get( 'memory_limit' ) );
$peak = memory_get_peak_usage( true ); // PHP が確保した量(上限と比べる値)
// 上限なし(-1)のときは記録しない。上限の 80% を超えたリクエストだけ記録する
if ( $limit <= 0 || $peak < $limit * 0.8 ) {
return;
}
error_log( sprintf(
'[memory] peak %s / limit %s (%d%%) %s %s',
size_format( $peak, 1 ),
ini_get( 'memory_limit' ),
(int) round( $peak / $limit * 100 ),
isset( $_SERVER['REQUEST_METHOD'] ) ? $_SERVER['REQUEST_METHOD'] : 'CLI',
isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : ''
) );
} );
上限に達して致命的エラーになったリクエストは、エラーそのものがログに残ります。このコードは、その手前まで使っているリクエストを見つけるためのものです。調査が終わったら削除してください。
手順4:自作の一括処理でメモリを抑える
インポートや一括更新など、自分で書いた処理でメモリが足りなくなる場合は、上限を上げる前に処理の書き方を見直します。
<?php
// 重い一括処理の前に、この処理だけ上限を引き上げる
add_filter( 'my_bulk_update_memory_limit', function () {
return '512M';
} );
function my_bulk_update_posts() {
wp_raise_memory_limit( 'my_bulk_update' );
$paged = 1;
do {
$ids = get_posts( array(
'post_type' => 'post',
'post_status' => 'any',
'fields' => 'ids', // ID だけを取得する
'posts_per_page' => 100,
'paged' => $paged,
'orderby' => 'ID',
'order' => 'ASC',
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
) );
foreach ( $ids as $id ) {
// 1件ずつの処理(例: メタ情報の更新)
update_post_meta( $id, '_my_checked', 1 );
}
// このリクエスト内のオブジェクトキャッシュだけを捨てる(サイト全体のキャッシュは消さない)
if ( wp_cache_supports( 'flush_runtime' ) ) {
wp_cache_flush_runtime();
}
$paged++;
} while ( count( $ids ) === 100 );
}
コードの要点は次のとおりです。
wp_raise_memory_limit():WordPress が用意している関数で、引数の文字列(コンテキスト)に応じたフィルターを通して上限を引き上げます。コア自身はadmin(管理画面)、image(画像処理)、cron(WP-Cron)で呼び、フィルター名はそれぞれadmin_memory_limit、image_memory_limit、cron_memory_limitです。独自のコンテキスト名を渡すと{コンテキスト名}_memory_limitというフィルターが使われるので、上の例ではmy_bulk_update_memory_limitでこの処理の上限だけを決めています。フィルターを付けなければWP_MAX_MEMORY_LIMITまで引き上げます。サーバー側でmemory_limitが固定されている場合は何もしません。- 件数を区切って取得する:全件を一度に読み込まず、100件ずつ取得します。
fields => 'ids'で投稿オブジェクトを作らず、no_found_rowsとupdate_post_*_cache => falseで不要な集計やキャッシュの読み込みを省きます。 wp_cache_flush_runtime():WordPress 6.0 で追加された関数で、そのリクエストのメモリ上に溜まったオブジェクトキャッシュを捨てます。wp_cache_flush()は Redis などの永続オブジェクトキャッシュを使っている場合にサイト全体のキャッシュを消してしまい、他の訪問者の表示が遅くなるので、ループ内では使いません。永続キャッシュのプラグインによってはflush_runtimeに対応していないため、wp_cache_supports()で確かめてから呼んでいます。- 処理の中で投稿を書き換えて、取得条件に合う投稿の数が変わる場合は、
pagedで進めると取りこぼしが出ます。その場合は、処理済みの最大 ID より大きいものを取得する方式にします。
wp-config.php で SAVEQUERIES を有効にしていると、実行したすべての SQL がメモリに溜まります。大量の処理を流すときは無効にしておきます。
「Out of memory」と表示される場合
「Allowed memory size of … exhausted」ではなく「Fatal error: Out of memory (allocated …)」と出る場合は、PHP の上限ではなく、サーバーそのもののメモリが足りずに確保できなかったことを示します。memory_limit を上げても直らないので、サーバーの空きメモリ、PHP-FPM の同時プロセス数(pm.max_children)、他のプロセスの使用量を見直します。
まとめ
- エラーの「Allowed memory size of」の数値で、当たった上限(40M なら
WP_MEMORY_LIMITの既定値、128M なら PHP の既定値など)を判断します。 WP_MEMORY_LIMITは PHP の設定より大きい値でもini_set()で引き上げます。効かない場合はサーバー側で固定されているので、php.ini、.user.ini、コントロールパネルで PHP のmemory_limitを変えます。- 上限を上げる前後に、WP-CLI の
--skip-plugins、Query Monitor、Health Check & Troubleshooting で原因のプラグインを切り分けます。 - 自作の一括処理では、件数を区切って ID だけを取得し、
wp_cache_flush()ではなくwp_cache_flush_runtime()でメモリを空けます。上限の引き上げはwp_raise_memory_limit()と独自コンテキストのフィルターで、その処理だけに限定します。