Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 38218371 bytes)
即 128MB 限制不足。
; php.ini
memory_limit = 256M
; 或
memory_limit = 512M
; 或取消限制 (極度慎用)
memory_limit = -1
; 代碼動態
ini_set('memory_limit', '512M');
<?php
// 1. 及時釋放大變量
$largeData = fetchLargeData();
process($largeData);
unset($largeData); // 關鍵!
// 2. 分批處理大數據集
function processInBatches($data, $batchSize = 100) {
foreach (array_chunk($data, $batchSize) as $batch) {
processBatch($batch);
// 循環結束自動釋放 $batch
}
}
// 3. 生成器懶加載 (PHP 5.5+)
function fetchLargeDataGenerator() {
$handle = fopen('huge.csv', 'r');
while (($row = fgetcsv($handle)) !== false) {
yield $row; // 一次只在內存保留一行
}
fclose($handle);
}
foreach (fetchLargeDataGenerator() as $row) {
processRow($row);
}
// 4. 數據庫查詢只選需要字段
// 錯誤: SELECT * FROM huge_table
// 正確: SELECT id, name FROM huge_table
// 5. 避免數組不必要的複製
// 錯誤: $copy = $hugeArray;
// 正確: 引用傳遞或指針操作
<?php
function memoryCheck($label = '') {
$mem = memory_get_usage(true);
$peak = memory_get_peak_usage(true);
printf("%s: 當前 %.2f MB, 峰值 %.2f MB<br>", $label, $mem/1024/1024, $peak/1024/1024);
}
memoryCheck('開始');
// 業務邏輯...
memoryCheck('處理後');
unset($largeVar);
memoryCheck('釋放後');
total runtime: 1.47 s
memory usage: 77.09 MB
// 單頁面 77MB,原因:20個SQL查詢 × 10行結果 × 10KB/行 = 2MB 數組
// 但程序從未 unset,累積導致峰值飆升
php -d memory_limit=-1 composer.phar update| 策略 | 優先級 | 說明 |
|---|---|---|
| 代碼優化 (unset/分批/生成器) | 最高 | 治本,無副作用 |
| 合理設置 memory_limit | 高 | 峰值 × 1.5-2 |
| 監控峰值報警 | 高 | 事前發現 |
| 升級 PHP 版本 | 中 | 新版本內存管理更優 |
| 無限制 -1 | 最低 | 風險極大,僅臨時調試 |