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
<?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
<?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
}
}
<?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。memory_get_peak_usage() 可能回傳 0 (視 PHP 版本)。true 參數較能反映實際 RSS。memory_limit 避免佔滿系統記憶體。