PHP Conference Japan 2024

memory_get_usage

(PHP 4 >= 4.3.2, PHP 5, PHP 7, PHP 8)

memory_get_usage傳回配置給 PHP 的記憶體數量

說明

memory_get_usage(布林值 $real_usage = false): 整數

以位元組為單位傳回目前配置給 PHP 指令碼的記憶體數量。

參數

real_usage

設定此參數為 true 以取得從系統分配的總記憶體,包含未使用的頁面。如果未設定或設為 false,則只會回報已使用的記憶體。

注意事項:

PHP 並不會追蹤非由 emalloc() 所配置的記憶體。

回傳值

回傳記憶體使用量,單位為位元組。

範例

範例 #1 memory_get_usage() 範例

<?php
// 這只是一個範例,以下的數字會
// 根據您的系統而有所不同

echo memory_get_usage() . "\n"; // 36640

$a = str_repeat("Hello", 4242);

echo
memory_get_usage() . "\n"; // 57960

unset($a);

echo
memory_get_usage() . "\n"; // 36744

?>

參見

新增註釋

使用者貢獻的註釋 12 則註釋

xelozz -at- gmail.com
14 年前
以 KB 或 MB 取得記憶體使用量

<?php
function convert($size)
{
$unit=array('b','kb','mb','gb','tb','pb');
return @
round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}

echo
convert(memory_get_usage(true)); // 123 kb
?>
Alex Aulbach
13 年前
請注意,KB、MB 等的正式 IEC 字首分別為 KiB、MiB、TiB 等。

請見 http://en.wikipedia.org/wiki/Tebibyte

乍看之下,這聽起來像是「搞什麼?大家都知道,我們指的是 1024 而不是 1000,而且差異不大,所以呢?」。但大約 10 年後,硬碟的大小(以及上面的檔案)將達到 PB 的限制,屆時 PB 和 PiB 之間的差異將會非常巨大。

最好現在就習慣它 :)
stanislav.eckert@vizson.de
7 年前
memory_get_usage() 僅用於擷取分配給 PHP(或您正在執行的腳本)的記憶體。但直覺上,許多人期望根據函數名稱取得系統的記憶體使用量。

因此,如果您需要整體記憶體使用量,以下函數可能會有幫助。它會以百分比(不含百分比符號)或位元組為單位擷取記憶體使用量,方法是返回一個包含系統可用記憶體和總記憶體的陣列。已在 Windows (7) 和 Linux(在 Raspberry Pi 2 上)測試過

<?php

// Returns used memory (either in percent (without percent sign) or free and overall in bytes)
function getServerMemoryUsage($getPercentage=true)
{
$memoryTotal = null;
$memoryFree = null;

if (
stristr(PHP_OS, "win")) {
// Get total physical memory (this is in bytes)
$cmd = "wmic ComputerSystem get TotalPhysicalMemory";
@
exec($cmd, $outputTotalPhysicalMemory);

// Get free physical memory (this is in kibibytes!)
$cmd = "wmic OS get FreePhysicalMemory";
@
exec($cmd, $outputFreePhysicalMemory);

if (
$outputTotalPhysicalMemory && $outputFreePhysicalMemory) {
// Find total value
foreach ($outputTotalPhysicalMemory as $line) {
if (
$line && preg_match("/^[0-9]+\$/", $line)) {
$memoryTotal = $line;
break;
}
}

// Find free value
foreach ($outputFreePhysicalMemory as $line) {
if (
$line && preg_match("/^[0-9]+\$/", $line)) {
$memoryFree = $line;
$memoryFree *= 1024; // convert from kibibytes to bytes
break;
}
}
}
}
else
{
if (
is_readable("/proc/meminfo"))
{
$stats = @file_get_contents("/proc/meminfo");

if (
$stats !== false) {
// Separate lines
$stats = str_replace(array("\r\n", "\n\r", "\r"), "\n", $stats);
$stats = explode("\n", $stats);

// Separate values and find correct lines for total and free mem
foreach ($stats as $statLine) {
$statLineData = explode(":", trim($statLine));

//
// Extract size (TODO: It seems that (at least) the two values for total and free memory have the unit "kB" always. Is this correct?
//

// Total memory
if (count($statLineData) == 2 && trim($statLineData[0]) == "MemTotal") {
$memoryTotal = trim($statLineData[1]);
$memoryTotal = explode(" ", $memoryTotal);
$memoryTotal = $memoryTotal[0];
$memoryTotal *= 1024; // convert from kibibytes to bytes
}

// Free memory
if (count($statLineData) == 2 && trim($statLineData[0]) == "MemFree") {
$memoryFree = trim($statLineData[1]);
$memoryFree = explode(" ", $memoryFree);
$memoryFree = $memoryFree[0];
$memoryFree *= 1024; // convert from kibibytes to bytes
}
}
}
}
}

if (
is_null($memoryTotal) || is_null($memoryFree)) {
return
null;
} else {
if (
$getPercentage) {
return (
100 - ($memoryFree * 100 / $memoryTotal));
} else {
return array(
"total" => $memoryTotal,
"free" => $memoryFree,
);
}
}
}

function
getNiceFileSize($bytes, $binaryPrefix=true) {
if (
$binaryPrefix) {
$unit=array('B','KiB','MiB','GiB','TiB','PiB');
if (
$bytes==0) return '0 ' . $unit[0];
return @
round($bytes/pow(1024,($i=floor(log($bytes,1024)))),2) .' '. (isset($unit[$i]) ? $unit[$i] : 'B');
} else {
$unit=array('B','KB','MB','GB','TB','PB');
if (
$bytes==0) return '0 ' . $unit[0];
return @
round($bytes/pow(1000,($i=floor(log($bytes,1000)))),2) .' '. (isset($unit[$i]) ? $unit[$i] : 'B');
}
}

// Memory usage: 4.55 GiB / 23.91 GiB (19.013557664178%)
$memUsage = getServerMemoryUsage(false);
echo
sprintf("Memory usage: %s / %s (%s%%)",
getNiceFileSize($memUsage["total"] - $memUsage["free"]),
getNiceFileSize($memUsage["total"]),
getServerMemoryUsage(true)
);

?>

不需要 getNiceFileSize() 函數。僅用於縮短位元組大小。

注意:如果您需要伺服器負載(CPU 使用率),我也寫了一個不錯的函數來獲取它:https://php.dev.org.tw/manual/en/function.sys-getloadavg.php#118673
jeff.peck@snet.net
15 年前
以 KB 或 MB 取得記憶體使用量

<?php
function echo_memory_usage() {
$mem_usage = memory_get_usage(true);

if (
$mem_usage < 1024)
echo
$mem_usage." 位元組";
elseif (
$mem_usage < 1048576)
echo
round($mem_usage/1024,2)." KB";
else
echo
round($mem_usage/1048576,2)." MB";

echo
"<br/>";
}
?>
lorin.weilenmann@gmail.com
14 年前
我可以確認此函數會觸發垃圾回收。我有一個腳本在某個時間點超過了 128MB 的記憶體,並以致命錯誤結束。我很困惑,因為該腳本最初處理了一些大檔案,但從那時起的記憶體負載應該是微不足道的,並且錯誤發生在最後。

這些大檔案是在一個專用函數中處理的,我甚至在檔案寫入磁碟後,在該函數內使用 unset() 處理保存檔案的變數。因此,記憶體應該已被清除兩次,第一次是在 unset() 呼叫之後,第二次是在函數結束之後。

為了除錯記憶體使用情況,我在某些點呼叫了 memory_get_usage(true) 並顯示了記憶體分配。只需在腳本中添加一些顯示,記憶體使用量就不會超過 1MB 的額外開銷(在當前檔案大小之上),並且記憶體錯誤消失了。
randolphothegreat@yahoo.com
20 年前
[danbrown AT php DOT net 編輯:作者的意圖是僅在 PHP 4 < 4.3.2 中使用。]

我想指出的是,雖然 sandeepc at myrealbox dot com 提出的顯示目前記憶體用量的方法不錯,但透過 grep 處理整個程序列表可能不是個好主意。效能更好的方法是只選取我們感興趣的程序。

<?php
$pid
= getmypid();
error_log('記憶體用量 (% KB PID ): ' . `ps --pid $pid --no-headers -o%mem,rss,pid`);
?>

的確,效能提升不多,但一點一滴都有幫助。
yousha dot a at hotmail dot com
6 年前
請注意,`memory_get_usage` 的說明與其預設參數不同!

"`int memory_get_usage ([ bool $real_usage = FALSE ] )`
傳回目前配置給 PHP 腳本的記憶體量(以位元組為單位)。"

預設參數 = `FALSE`

錯誤說明:傳回目前配置給 PHP 腳本的記憶體量(以位元組為單位)。

應該是:傳回 PHP 腳本目前使用的記憶體量(以位元組為單位)。
ad-rotator.com
20 年前
sandeepc at myrealbox dot com 發布的方法會產生較大的記憶體用量,我猜測它包含了所有 PHP 直譯器/內部程式碼,而不僅僅是正在執行的腳本。

1) 使用 ps 命令
記憶體用量 (% KB PID ): 0.8 12588 25087 -> 約 12MB
2) 使用 memory_get_usage()
int(6041952) -> 約 6MB
miami at blackcrystal dot net
9 年前
有時,我們需要所有記憶體來執行我們的任務,我們會使用 ini_set('memory_limit', -1 ),或我們擁有的最大值。

為了避免伺服器在長時間且消耗大量記憶體的任務中卡住,我寫了這個檢查。這與 memory_get_usage() 的作用不同,但更多。它顯示程序佔用的虛擬記憶體量,以百分比表示。

<?php
function getVirtualMemoryTaken()
{
$pid = getmypid();
$a = `ps -p $pid v | awk 'END{print $9}'`;
return
$a*1;
}
?>

它僅適用於 Linux,已在 Ubuntu 14 中測試。

<?php
$a
= ' ';
do {
$a .= $a . $a; }
while (
getVirtualMemoryTaken() < 20 );
?>
vesa dot kivisto at nepton dot fi
19 年前
[danbrown AT php DOT net 編輯:此函數僅適用於伺服器已安裝必要第三方軟體的 Windows 版本 PHP。]

我無法讓先前的範例正常運作,因此建立了至少對我來說可行的程式碼。敬請享用!

<?php
// 請注意,您需要從 http://www.sysinternals.com/Utilities/PsTools.html 下載 pslist.exe 工具程式
// 這是因為 Win/2000 本身沒有提供工作清單工具程式。
//
function getMemoryUsage() {

// 嘗試使用 PHP 內建函式
if( function_exists('memory_get_usage') ) {
return
memory_get_usage();
}

// 嘗試透過 pslist 命令取得 Windows 記憶體使用量
if ( substr(PHP_OS,0,3) == 'WIN') {

$resultRow = 8;
$resultRowItemStartPosition = 34;
$resultRowItemLength = 8;

$output = array();
exec('pslist -m ' . getmypid() , $output);

return
trim(substr($output[$resultRow], $resultRowItemStartPosition, $resultRowItemLength)) . ' KB';

}


// 無任何可用的記憶體功能
return '<b style="color: red;">無數值</b>';

}
?>
e dot a dot schultz at gmail dot com
18 年前
這是一個適用於 Windows XP/2003 和大多數 UNIX 與 Mac OS X 發行版的函式。

<?php
if( !function_exists('memory_get_usage') )
{
function
memory_get_usage()
{
//如果是 Windows 系統
//在 Win XP Pro SP2 上測試過。應該也能在 Win 2003 Server 上運作
//不適用於 2000
//如果您需要它適用於 2000,請參考 http://us2.php.net/manual/en/function.memory-get-usage.php#54642
if ( substr(PHP_OS,0,3) == 'WIN')
{
if (
substr( PHP_OS, 0, 3 ) == 'WIN' )
{
$output = array();
exec( 'tasklist /FI "PID eq ' . getmypid() . '" /FO LIST', $output );

return
preg_replace( '/[\D]/', '', $output[5] ) * 1024;
}
}else
{
//現在假設作業系統是 UNIX
//在 Mac OS X 10.4.6 和 Linux Red Hat Enterprise 4 上測試過
//這應該適用於大多數 UNIX 系統
$pid = getmypid();
exec("ps -eo%mem,rss,pid | grep $pid", $output);
$output = explode(" ", $output[0]);
//rss 以 1024 位元組為單位
return $output[1] * 1024;
}
}
}
?>
MagicalTux at FF dot st
19 年前
當您需要取得作業系統時,不要使用 $_SERVER['OS'] 或 $_ENV['OS'],最好使用 PHP_OS 常數!
<?php
if (substr(PHP_OS,0,3)=='WIN') {
// [...]
}
?>

您還可以取得其他值,例如 CYGWIN_NT-5.0、Linux 等…這是取得系統作業系統的最佳方法(任何 Linux 使用者都可以執行「export OS=windows」)
To Top