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

PHP 記憶體溢出解決方案與 unset 釋放機制深度解析

     編輯:PHP 綜合知識

一、大數據處理的分批釋放策略

處理大量資料(如 50 萬筆日誌)時,單次載入全量陣列極易觸發 memory_limit。核心原則:**分批處理、用完即銷毀**。

<?php
ini_set('memory_limit', '64M');
set_time_limit(600);

$batchSize = 10000;
$handle = fopen($logFile, 'r');

while (!feof($handle)) {
    $batch = [];
    for ($i = 0; $i < $batchSize && !feof($handle); $i++) {
        $batch[] = fgets($handle);
    }
    // 處理當前批次
    processBatch($batch);
    // 顯式釋放
    unset($batch);
}
fclose($handle);

function processBatch(array $lines) {
    foreach ($lines as $line) {
        // 解析、統計、寫入 DB 等
    }
}
?>

二、unset 釋放記憶體的實測結論

結論 1:變數值佔用 > 256 位元組時,unset 才會釋放記憶體

<?php
$s = str_repeat('1', 255); // 255 位元組
$m = memory_get_usage();
unset($s);
echo memory_get_usage() - $m; // 0,未釋放

$s = str_repeat('1', 256); // 256 位元組
$m = memory_get_usage();
unset($s);
echo memory_get_usage() - $m; // 272,已釋放
?>

結論 2:存在引用變數時,需全部 unset 才會釋放

<?php
$s = str_repeat('1', 256);
$p = &$s; // 建立引用
$m = memory_get_usage();
unset($s); // 僅銷毀 $s,$p 仍指向記憶體
echo memory_get_usage() - $m; // 0,未釋放

// 正確做法:同時銷毀所有引用
unset($s, $p); // 或 $s = null; $p = null;
// 此時記憶體才會釋放
?>

三、實務建議

  • 大陣列分批讀取(array_splice、Generator、資料庫游標)。
  • 迴圈內及時 unset 暫存變數。
  • 避免不必要的引用(&),除非明確需要修改原值。
  • 物件使用完畢呼叫 __destruct() 或 unset($obj)。
  • 資料庫連線、檔案控制代碼用完立即關閉。
  • 調整 memory_limit 視專案需求,但不應作為唯一解法。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved