首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP Fatal error: Allowed memory size exhausted 解決方案與根因排查

     編輯:PHP 相關知識

報錯 Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 72 bytes) 表示腳本申請內存超過 memory_limit 限制。解決分三層:臨時調大、代碼優化、架構重構。

第一梯隊:配置調大(治標)

方式生效範圍示例
php.ini全局永久memory_limit = 256M
.user.ini (PHP-FPM)目錄遞歸memory_limit = 256M
.htaccess (Apache mod_php)目錄遞歸php_value memory_limit 256M
ini_set()當前腳本ini_set('memory_limit', '256M');
命令行參數單次執行php -d memory_limit=512M script.php

注意:修改 php.ini 後**必須重啟 PHP-FPM/Apache** 生效;ini_set 在腳本啟動早期調用(如入口文件頂部)。

第二梯隊:代碼層面根因排查與優化(治本)

  1. 死循環/遞歸無終止條件:檢查 while(true)、遞歸函數是否有明確 break/return。
  2. 一次性載入超大數據:
    • file_get_contents('huge.log') → 改用 fopen() + fgets() 流式讀取。
    • SELECT * FROM big_table → 分頁游標 LIMIT 1000 OFFSET ... 或 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false 游標模式。
    • json_decode($hugeJson) → 改用 halaxa/json-stream 流式解析。
  3. 數組/對象未釋放累積:循環內創建大對象後 unset($obj) 或重用變量;gc_collect_cycles() 強制回收循環引用(PHP 5.3+)。
  4. Composer 自動載入類映射過大:生產環境執行 composer dump-autoload -o --classmap-authoritative 優化。
  5. 圖片處理/導出 Excel:改用 Box/Spout 流式寫入、Imagick 替代 GD(內存外處理)。
  6. Xdebug 開啟導致內存暴漲:生產環境**禁用** Xdebug。

第三梯隊:架構級方案(徹底解決)

  • 異步隊列:耗內存任務(報表生成、視頻轉碼、大數據同步)推入 Redis/RabbitMQ,由獨立 Worker 消費(可單獨配置高 memory_limit)。
  • 分片/流式處理:將大任務拆分為多個小任務,每個任務處理固定批次數據。
  • 遷移至長運行進程框架:Swoole、RoadRunner、Workerman 常駐內存,避免重複啟動開銷,並可精細控制內存生命週期。

排查工具鏈

# 1. 記錄峰值內存
echo 'Peak: ' . memory_get_peak_usage(true) / 1024 / 1024 . ' MB';

# 2. XHProf / Blackfire 火焰圖定位內存熱點函數

# 3. memory_get_usage() 埋點關鍵節點對比

# 4. php -d memory_limit=-1 script.php 臨時無限制跑通驗證邏輯

核心原則:**配置調大只為爭取時間,代碼優化才是正道,架構重構才是終局**。建立內存監控告警(如峰值超 70% limit 觸發通知),讓問題在用戶感知前被發現。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved