【WordPress PHPエラー】Fatal error: Allowed memory size of xxx bytes exhausted

Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 430080 bytes) in /home/xxxx/public_html/xxxxx.com/wp-includes/wp-db.php on line xxxx

WordPressで固定ページを編集しようと編集をクリックすると上記エラーが発生してしまいました。

PHPのメモリ不足が原因のようです

詳しく言うと、許可されているメモリサイズ(268435456 bytes = 256MB)を使い果たして、

さらに397312 bytes(約388KB)の追加メモリ割りあてようとしたら失敗したようです

おそらく原因は固定ページ内に大量の画像ブロックを配置しているから

WordPressの編集画面でのメモリ問題 500KB × 400枚… メモリ使用量 PHPのメモリ制限に近い状態 発生する問題: 1. 編集画面を開く時にメモリエラー 2. 保存時にメモリエラー 3. 画面の応答が遅い
https://internet.mints.ne.jp/%e3%83%af%e3%83%bc%e3%83%89%e3%83%97%e3%83%ac%e3%82%b9%e3%81%ae%e3%83%a1%e3%83%87%e3%82%a3%e3%82%a2%e3%81%ab%e4%bf%9d%e5%ad%98%e3%81%97%e3%81%9f%e7%94%bb%e5%83%8f%e3%81%a8%e3%83%87%e3%83%bc%e3%82%bf

メモリの上限

メモリの制限は複数の層で設定されています

レンタルサーバー(PHP)の制限 php.ini による制限 (例:256MB) WordPress の制限 wp-config.php による制限 WordPressの制限は、PHPの制限を超えることができません
  1. レンタルサーバー(PHP)の制限
  • サーバーのphp.iniファイルで設定される制限
  • サーバー全体のPHPスクリプトに適用される最大メモリ使用量
  • レンタルサーバーの管理画面やFTPでphp.iniをアップロードすることで変更可能
  1. WordPressの制限
  • WordPressのwp-config.phpファイルで設定される制限
  • PHPの制限を超えて設定することはできない
    • 例:PHPの制限が256MBの場合、WordPressで512MBと設定しても256MBまでしか使用できない

1)サーバー全体のPHPで設定されるメモリ制限

これが最も上位の制限となり、この値を超えることはできない

通常、レンタルサーバーの管理画面やサポートでのみ変更可能

メモリの確認方法

ルードディレクトリに下記の様なphpファイルを設置しアクセスし、memory_limitを確認できます

info.php

<?php phpinfo(); ?>

↓アクセスしてみるとメモリ上限が確認できます

php.iniで上限をふやせます

お名前ドットコムをレンタルサーバーで使用している場合は下記の記事を参考できます。

ご利用サーバーのFTPサーバーへご接続いただき、該当ドメインディレクトリ直下に
エラーの内容以上のメモリサイズを記述した「php.ini」ファイルを設置(アップロード)してください。
※既に「php.ini」ファイルを設置されている場合には、同ファイルを修正してください。

https://help.onamae.com/answer/20364

レンタルサーバー側からメモリの使用が集中してアクセス制限がかかることがあります

「ERR_CONNECTION_TIMED_OUT」エラーの解決方法

https://help.onamae.com/answer/20364

2)WordPress側のメモリ

  • WP_MEMORY_LIMIT:通常時の制限(デフォルト40M)
  • WP_MAX_MEMORY_LIMIT:管理画面での制限(デフォルト256M)

ワードプレスのメモリは管理画面のツールのサイトヘルスから確認できます

一時的にメモリ制限を大幅に引き上げる方法:

// wp-config.phpに追加
define('WP_MEMORY_LIMIT', '256M');
define('WP_MAX_MEMORY_LIMIT', '512M');

wp-config.php冒頭の<?phpの次の行に追記しました

↓サイトヘルスで変更が確認できました

https://sologaku.com/wordpress/how-to-change-wordpress-memory-limit/#google_vignette

対処法

今回のエラー

Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate…

はどちらのエラー??

Fatal error: [エラーの説明] in [ファイルのパス] on line [行番号]

はPHPのエラーメッセージの形式

WordPressメディアライブラリから画像データそのものを削除すると、固定ページ上のギャラリーブロックに関連付けられていた画像の参照が切れ、メモリ消費が減少するため、編集画面に遷移できる可能性が高い

ただし、以下の点に注意が必要です:

  1. メディアライブラリから画像を削除した場合:
  • 固定ページ上のギャラリーブロックは残りますが、削除した画像は「見つかりません」や空の枠として表示される
  • ブロックエディタで開くと、画像が欠落したギャラリーブロックとして表示される
  • サイト上では画像が表示されなくなる
  1. 推奨される手順:
  • まずサイトとデータベースのバックアップを取る
  • メディアライブラリから、問題のページで使用している画像を一部削除
  • 編集画面にアクセスできるようになったら、不要なギャラリーブロックを整理
  • 必要な画像は最適化して再アップロード
  1. より安全な代替アプローチ:
  • まず、wp-config.phpでメモリ制限を一時的に引き上げてから
  • 画像の整理と最適化を行う方が、データの制御がしやすい

このアプローチで編集画面にアクセスできるようになったら、今後のために:

必要に応じてギャラリーの分割 を検討することをお勧めします。

画像サイズの最適化

1ページあたりの画像数の制限

ワードプレスのデバッグモードを有効にして詳細なエラー情報を確認:

// wp-config.phpに追加
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);

遅延読み込み(Lazy Loading)

遅延読み込みとは: 画面に表示されている部分の画像だけを読み込み、見えていない部分の画像は後回しにする仕組みです。

表示エリア(画像読み込み済み) スクロール下の画像(未読み込み)
// functions.php
function add_lazy_loading_to_admin() {
    // 管理画面でのみ実行
    if (is_admin()) {
        // インラインでJavaScriptを追加
        wp_add_inline_script('jquery', '
            jQuery(document).ready(function($) {
                // 画像を監視するための設定
                const observer = new IntersectionObserver((entries) => {
                    entries.forEach(entry => {
                        if (entry.isIntersecting) {
                            const img = entry.target;
                            if (img.dataset.src) {
                                img.src = img.dataset.src;
                                img.removeAttribute("data-src");
                            }
                        }
                    });
                });

                // 編集画面内の画像を処理
                $("#post-body img").each(function() {
                    const img = $(this);
                    const originalSrc = img.attr("src");
                    img.attr("data-src", originalSrc);
                    img.attr("src", "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
                    observer.observe(img[0]);
                });
            });
        ');
    }
}
add_action('admin_enqueue_scripts', 'add_lazy_loading_to_admin');

リスクについて

リスクは比較的低いです。理由は:

  1. 編集画面のみの変更
    • 公開サイトには影響なし
    • 画像データ自体は変更しない
  2. 簡単に元に戻せる
    • functions.phpから該当コードを削除するだけ
  3. エラーが起きても
    • 最悪の場合、画像が表示されないだけ
    • WordPressの基本機能は影響を受けない

筆者はこの方法ではメモリ数は抑えることはできませんでした…

データベースクエリとリビジョンを対策

データベースクエリとは:

  • WordPressがデータベースにデータを要求する際の命令
  • 例:
    • 記事の内容を取得
    • 画像情報の取得
    • カスタムフィールドの取得
  • 一つのページを表示するために、多数のクエリが実行される
  • 各クエリの結果はメモリに保存される

リビジョンとは:

  • 記事の変更履歴を保存する機能
  • 保存する度に新しいバージョンが作られる
  • デフォルトでは無制限に保存される
  • 各バージョンがデータベースに保存され、編集画面で読み込まれる
WordPressのメモリ消費要因 データベースクエリ 投稿データの取得 メタデータの取得 カスタムフィールドの取得 リビジョン 最新版 1つ前のバージョン 2つ前のバージョン メモリ消費要因の説明: 1. データベースクエリ: ・1回のページ表示で数十〜数百のクエリが実行 ・各クエリ結果がメモリに保存される 2. リビジョン: ・記事の変更履歴が全て保存される ・各バージョンの内容がメモリに読み込まれる

データベースクエリの設定を最適化

WordPressのデフォルト設定と最適化後 デフォルト設定 取得データ一覧 ・ID ・post_title(タイトル) ・post_content(本文) ・post_excerpt(抜粋) ・post_status(状態) ・comment_status(コメント設定) ・ping_status(ピング設定) ・post_password(パスワード) ・post_name(スラッグ) ・to_ping(ピング先) ・pinged(ピング済み) 最適化後 必要最小限のデータ ・ID ・post_title(タイトル) ・post_content(本文)
// 必要な項目のみを取得するように変更
function optimize_post_queries() {
    add_filter('posts_fields', function($fields) {
        global $wpdb;
        // 必要最小限のフィールドのみを指定
        return "{$wpdb->posts}.ID, {$wpdb->posts}.post_title, {$wpdb->posts}.post_content";
    });
}
add_action('init', 'optimize_post_queries');

リスク:高い

WordPressのコア処理に介入するため、エラーが発生すると編集画面が開けなくなる可能性がある

リビジョンの最適化

リビジョンのデフォルト設定:

  • デフォルトでは無制限(制限なし)
  • 自動保存は60秒間隔
  • 全てのリビジョンがデータベースに保存される
// wp-config.php に追加するだけ
define('WP_POST_REVISIONS', 5);  // リビジョンを5個に制限

上記の手順ではリビジョンの設定変更後、既存のリビジョンは自動的には削除されません

プラグイン「WP-Sweep」

筆者の編集画面でのエラーは解消されましたが、画像を削除している最中何回か保存したら下記アクセス制限がかかりました。