修正 WordPress 的「Allowed Memory Size Exhausted」錯誤
如果你的網站顯示 Fatal error: Allowed memory size of 268435456 bytes exhausted,請在 wp-config.php 的 / That's all, stop editing! / 之前加入這一行。
發布於
如果你的網站顯示 Fatal error: Allowed memory size of 268435456 bytes exhausted,請在 wp-config.php 的 /* That's all, stop editing! */ 註解之前加入這一行:define( 'WP_MEMORY_LIMIT', '256M' );。這能讓大多數網站在一分鐘內恢復上線。但在你離開之前,請把這一頁的其餘內容讀完,因為調高上限只是一種診斷,不是治本。如果程式在更高的數字下再次崩潰,真正的問題就出在無限制消耗記憶體的程式碼,把上限拉高只是給它更多繼續失控的空間。
這個錯誤到底代表什麼
PHP 會追蹤每個請求已配置了多少記憶體。當單一請求試圖配置超過 php.ini 中所設定的 memory_limit(或被 WordPress 覆寫的值)時,PHP 會立即以嚴重錯誤終止該請求,並印出它掛掉時的位元組數。268435456 bytes 就是 256M,134217728 是 128M,536870912 是 512M。「tried to allocate」後面的數字告訴你的是壓垮駱駝的最後一根稻草有多大,而不是問題本身有多大。
WordPress 在 PHP 之上又疊了自己的限制。WP_MEMORY_LIMIT(預設 40M,若 PHP 上限更高則採用 PHP 值)管的是前台。WP_MAX_MEMORY_LIMIT(預設 256M)管的是後台端的操作,例如媒體庫和外掛更新,這些操作確實需要更多記憶體。WordPress 載入時會根據這些常數呼叫 ini_set('memory_limit', ...),但前提是你的主機允許使用 ini_set,而且只能提高到主機設定的硬上限為止。最後這一點,正是為什麼修改 wp-config.php 有時看起來毫無作用的原因。
依序修正
1. 在 wp-config.php 中調高 WordPress 的上限。 這是第一個該嘗試的做法,因為它可還原,而且不會動到其他任何東西。
define( 'WP_MEMORY_LIMIT', '256M' );
define( 'WP_MAX_MEMORY_LIMIT', '512M' );
如果你不確定這幾行該放在哪裡,或想同時把其他常見的常數也一併設定正確,我們的 wp-config 產生器 會產生一段乾淨的程式碼讓你直接貼上。位置很重要,任何放在「stop editing」那一行下方的內容都會被忽略。
2. 如果這樣還是沒用,代表你的主機在 PHP 層級設了上限。 在 PHP 層級調高 memory_limit。在 php.ini 中:
memory_limit = 256M
在許多共享主機上你無法直接編輯 php.ini。可以改試在網站根目錄放一個 .user.ini 檔案,或在 Apache/mod_php 環境下透過 .htaccess 設定:
php_value memory_limit 256M
請注意,.htaccess 中的 php_value 在 nginx 或 PHP-FPM 環境下會拋出 500 錯誤,因為它是 Apache/mod_php 專用的指令。如果你加了它之後出現 500,原因就在這裡,把它移除並改用 .user.ini。
3. 確認實際生效的數值。 別相信你編輯了什麼,要相信 PHP 回報的結果。在網站根目錄放一個只有一行的檔案:
<?php echo ini_get('memory_limit');
用瀏覽器載入它,讀取數值,然後刪除檔案。如果你設了 256M 之後它仍顯示 128M,代表你的主機正在覆寫你的設定,你需要聯絡他們或使用他們的控制台設定。
大多數教學都略過的部分
調高上限是診斷。以下是如何解讀結果。
如果你設了 256M 而網站在正常流量下維持正常運作,那你原本就是遇到了設得太低的合理上限,這在擁有大型媒體庫、WooCommerce 或頁面建構器的網站上很常見。你完成了。
如果你設了 256M 又崩潰,接著設 512M 又崩潰,別再往上調了。 正常的 WordPress 請求不需要 512M。當記憶體用量沒有上限地不斷攀升時,代表有東西在迴圈或累積:某個外掛把整張資料庫表載入到一個陣列裡、某個 add_action 遞迴觸發了自己、某個匯入程序一次把每一列都留在記憶體中,或是兩個外掛在同一個 hook 裡互相打架。調高上限並不會修好一個無限制的迴圈,它只是把崩潰往後推遲幾秒,並讓問題更難重現。
要找出元兇,請停用所有外掛,並切換到像 Twenty Twenty-Four 這樣的預設佈景主題。如果錯誤停止了,就一次重新啟用一個,直到錯誤再度出現。開啟除錯記錄,以便捕捉它掛掉的位置:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
wp-content/debug.log 中的嚴重錯誤那一行會指出配置最後一塊記憶體的檔案與行號。那通常就是迴圈本身,或是離它只有一個函式呼叫的距離。
不該做的事
別把 WP_MEMORY_LIMIT 設成 -1 或 1024M 然後就丟著不管。 無限記憶體不會修好記憶體洩漏,它只會讓一個失控的請求把整台伺服器吃光,這可能拖垮同一台機器上的所有其他網站,並讓你接到主機商的電話。上限是一種安全機制,留著它。
別把 ini_set('memory_limit', '512M') 貼進 functions.php 當作主要解法。 對某些故障來說它執行得太晚了,如果崩潰發生在 WordPress 核心載入期間、你的佈景主題 functions.php 執行之前,那一行永遠不會被執行到。wp-config.php 載入得更早,才是正確的位置。
別一口咬定這是主機問題就升級你的方案。 有時候確實是主機規格不足。但更常見的是,一模一樣的崩潰會跟著你到更大的方案上,因為病根隨著你的外掛一起搬過去了。先排除迴圈的可能,這不用花錢。
別為了修 max_execution_time 錯誤而去調高 memory_limit。 這是兩個不同的限制,訊息也不同。記憶體耗盡會顯示「Allowed memory size … exhausted」。逾時則會顯示「Maximum execution time … exceeded」。調錯了那一個會白白浪費你一個下午。
還是卡住了?
如果你已經確認實際生效的上限確實是 256M 或更高、也在關掉所有外掛並使用預設佈景主題的情況下測試過,而它仍然耗盡記憶體,那你面對的是一個值得在除錯記錄裡追查的真正洩漏,而不是一個值得調高的上限。抓下那一行嚴重錯誤,記下它指向的是哪個外掛的目錄,那就是你的錯誤回報。先用 wp-config 產生器 把 wp-config.php 的基準常數設定正確,這樣你才能確定上限真的設在你以為的位置,然後再去讀記錄。