報錯 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 在腳本啟動早期調用(如入口文件頂部)。
while(true)、遞歸函數是否有明確 break/return。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 流式解析。unset($obj) 或重用變量;gc_collect_cycles() 強制回收循環引用(PHP 5.3+)。composer dump-autoload -o --classmap-authoritative 優化。Box/Spout 流式寫入、Imagick 替代 GD(內存外處理)。memory_limit)。# 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 觸發通知),讓問題在用戶感知前被發現。