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

PHP 內建函數 memory_get_usage() 實戰:精準監控腳本記憶體佔用

     編輯:PHP 相關知識

PHP 內建函數 memory_get_usage() 實戰:精準監控腳本記憶體佔用

在 Web 開發中,記憶體洩漏、單腳本佔用過高導致 PHP-FPM 進程頻繁重啟、OOM Killer 介入等問題屢見不鮮。PHP 提供的 memory_get_usage() 與 memory_get_peak_usage() 兩大內建函數,能以字節級精度回報腳本當前及峰值記憶體分配量,是效能調優、洩漏排查的利器。

核心函數速查

函數返回值說明
memory_get_usage(bool $real_usage = false)int (bytes)當前腳本已分配記憶體;$real_usage=true 返回系統實際分配量 (含分配器元數據),false 僅返回 emalloc() 統計值。
memory_get_peak_usage(bool $real_usage = false)int (bytes)腳本啟動以來的記憶體分配峰值。
getrusage()array返回 CPU 時間、頁面錯誤、上下文切換等系統資源用量 (僅 Linux/Unix 支援)。
> ⚠️ 注意:上述函數在 Windows 環境下行為可能受限,建議在 Linux/生產環境一致的容器中測試。

實戰範例:觀測變量生命週期對記憶體的影響

<?php
echo '啟動記憶體:' . memory_get_usage() . \"\\n\";  // 147296

$tmp = str_repeat('hello', 1000);  // 分配約 5KB 字串
echo '分配後記憶體:' . memory_get_usage() . \"\\n\";  // 152456 (+5160 bytes)

unset($tmp);  // 釋放變量
echo '釋放後記憶體:' . memory_get_usage() . \"\\n\";  // 147296 回歸基線
?>

關鍵洞見:

  • unset() 能立即釋放變量佔用的 zval 結構體 及其引用的字串緩衝區,記憶體歸還給 PHP 分配器 (不一定歸還 OS)。
  • 大型陣列/物件處理完畢後主動 unset(),可顯著降低峰值記憶體,避免觸發 memory_limit。
  • 資源型別 (MySQL 結果集、檔案句柄、cURL handle) 同理,用畢即呼叫 mysqli_free_result()、fclose()、curl_close()。

進階技巧:人類可讀的記憶體格式化

function memory_usage_readable(): string
{
    if (!function_exists('memory_get_usage')) {
        return 'N/A';
    }
    $mb = memory_get_usage(true) / 1024 / 1024;
    return round($mb, 2) . ' MB';
}

// 使用示例
echo '當前記憶體:' . memory_usage_readable();  // 例如 2.34 MB

常見效能調優場景

  1. 對比算法/資料結構記憶體佔用:同樣處理 10 萬筆資料,Generator 迭代器 vs 陣列載入,前者記憶體恆定,後者線性增長。
  2. 定位記憶體洩漏點:在長運行腳本 (Worker、Queue Consumer) 關鍵節點埋點記錄 memory_get_usage(),配合 memory_get_peak_usage() 找出持續增長的區塊。
  3. 驗證緩存策略:比較 serialize() vs igbinary vs msgpack 序列化後字串大小,選擇最省記憶體的方案。
  4. 配合 microtime(true) 做時空綜合分析:記憶體-時間權衡曲線,找到最佳平衡點。

最佳實踐清單

  • ✅ 開發/測試環境關閉 OPcache 或設 opcache.enable_cli=0,避免緩存干擾基準測試。
  • ✅ 使用 memory_get_usage(true) 獲取系統實際分配量,更貼近 memory_limit 判定邏輯。
  • ✅ 針對 CLI 長腳本,定期檢查 memory_get_usage() > memory_limit * 0.8 並主動重啟/回收。
  • ✅ 結合 Xdebug/Blackfire/XHProf 做完整調用鏈分析,memory_get_usage() 只負責「快照」,不負責「定位」。

掌握 memory_get_usage() 系列函數,讓記憶體優化不再靠猜,而是憑數據說話。下次遇到「Allowed memory size exhausted」,請先在關鍵路徑埋點,再對症下藥!

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