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

PHP memory_get_usage() 記憶體分析實戰:監控腳本記憶體、峰值追蹤、效能調優

     編輯:PHP 綜合知識

前言

memory_get_usage() 回傳當前腳本已分配記憶體 (位元組),memory_get_peak_usage() 回傳峰值。兩者是 PHP 效能調優、記憶體洩漏偵測的核心工具。

基本用法

<?php
echo '起始: ' . memory_get_usage() . " bytes\n"; // 147,296

$tmp = str_repeat('hello', 1000); // 分配約 5KB 字串
echo '分配後: ' . memory_get_usage() . " bytes\n"; // 152,456

unset($tmp); // 釋放變數
echo '釋放後: ' . memory_get_usage() . " bytes\n"; // 147,296 (回到基線)

// 峰值
echo '峰值: ' . memory_get_peak_usage() . " bytes\n";

參數 $real_usage 差異

呼叫含義適用場景
memory_get_usage() / (false)Zend 記憶體管理器分配給腳本的記憶體 (emalloc)應用層記憶體趨勢分析
memory_get_usage(true)系統實際分配給進程的記憶體 (含分配器保留)容器/伺服器層級資源監控

人類可讀格式化函數

<?php
function formatBytes($bytes, $precision = 2) {
    $units = ['B', 'KB', 'MB', 'GB', 'TB'];
    $bytes = max($bytes, 0);
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
    $pow = min($pow, count($units) - 1);
    $bytes /= (1 << (10 * $pow));
    return round($bytes, $precision) . ' ' . $units[$pow];
}

echo formatBytes(memory_get_usage());      // 143.84 KB
echo formatBytes(memory_get_peak_usage()); // 148.88 KB

實戰場景

1. 比較兩種演算法記憶體佔用

<?php
function methodA($n) { $arr = []; for($i=0;$i<$n;$i++) $arr[] = $i; return $arr; }
function methodB($n) { yield from range(0, $n-1); } // Generator

$n = 100000;
$mem1 = memory_get_usage(); methodA($n); echo 'A: ' . formatBytes(memory_get_usage() - $mem1) . "\n"; // ~6.7 MB
$mem2 = memory_get_usage(); foreach(methodB($n) as $v); echo 'B: ' . formatBytes(memory_get_usage() - $mem2) . "\n"; // ~0.3 MB

2. 資料庫大量查詢分批處理

<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$stmt = $pdo->query('SELECT id, data FROM big_table');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    process($row);
    // 監控記憶體,超過閾值可暫停/重啟 worker
    if (memory_get_usage(true) > 200 * 1024 * 1024) { // 200 MB
        gc_collect_cycles(); // 強制 GC
    }
}

3. 記憶體洩漏偵測 (長跑 CLI)

<?php
// 在迴圈關鍵點記錄
$memLog = fopen('mem.log', 'a');
while (true) {
    doWork();
    fwrite($memLog, date('c') . " " . formatBytes(memory_get_usage(true)) . "\n");
    sleep(60);
}
// 事後用 Excel 畫圖,若曲線持續上升不回落 → 洩漏

常見釋放記憶體技巧

  • unset($largeVar) + gc_collect_cycles() (循環引用時)。
  • 資料庫結果集用 PDOStatement::fetch() 逐行處理,避免 fetchAll() 一次載入。
  • 大檔案用 fopen + fgets 流式讀取,勿 file_get_contents。
  • 生成器 yield 替代陣列回傳。
  • 及時 mysqli_free_result() / PDOStatement = null。

注意事項

  1. Windows 上 memory_get_peak_usage() 可能回傳 0 (視 PHP 版本)。
  2. OpCache 會共享部分記憶體,true 參數較能反映實際 RSS。
  3. CLI 長跑腳本建議設定 memory_limit 避免佔滿系統記憶體。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved