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 年前
请注意,千字节、兆字节等的官方 IEC 前缀为 KiB、MiB、TiB 等。

参见 http://en.wikipedia.org/wiki/Tebibyte

乍一看,这可能听起来像是“什么鬼?每个人都知道我们指的是 1024 而不是 1000,而且差异不大,所以有什么关系呢?”。但大约 10 年后,硬盘(以及其中的文件)的大小将达到 PB 限制,然后 PB 和 PiB 之间的差异将非常大。

最好现在就开始习惯它。 :)
stanislav dot eckert at vizson dot de
7 年前
memory_get_usage() 用于检索仅分配给 PHP(或正在运行的脚本)的内存。但直觉上,许多人根据函数名称期望获得系统内存使用情况。

因此,如果您需要整体内存使用情况,以下函数可能会有所帮助。它通过返回一个包含系统空闲内存和总内存的数组来以百分比(不带百分号)或字节为单位检索内存使用情况。已在 Windows(7)和 Linux(在 Raspberry Pi 2 上)上进行了测试

<?php

// 返回已用内存(以百分比(不带百分号)或以字节为单位返回空闲内存和总内存)
function getServerMemoryUsage($getPercentage=true)
{
$memoryTotal = null;
$memoryFree = null;

if (
stristr(PHP_OS, "win")) {
// 获取总物理内存(以字节为单位)
$cmd = "wmic ComputerSystem get TotalPhysicalMemory";
@
exec($cmd, $outputTotalPhysicalMemory);

// 获取空闲物理内存(以KiB为单位!)
$cmd = "wmic OS get FreePhysicalMemory";
@
exec($cmd, $outputFreePhysicalMemory);

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

// 查找空闲值
foreach ($outputFreePhysicalMemory as $line) {
if (
$line && preg_match("/^[0-9]+\$/", $line)) {
$memoryFree = $line;
$memoryFree *= 1024; // 将KiB转换为字节
break;
}
}
}
}
else
{
if (
is_readable("/proc/meminfo"))
{
$stats = @file_get_contents("/proc/meminfo");

if (
$stats !== false) {
// 分隔行
$stats = str_replace(array("\r\n", "\n\r", "\r"), "\n", $stats);
$stats = explode("\n", $stats);

// 分隔值并查找总内存和空闲内存的正确行
foreach ($stats as $statLine) {
$statLineData = explode(":", trim($statLine));

//
// 提取大小(TODO:似乎(至少)总内存和空闲内存的两个值始终以“kB”为单位。这是正确的吗?
//

// 总内存
if (count($statLineData) == 2 && trim($statLineData[0]) == "MemTotal") {
$memoryTotal = trim($statLineData[1]);
$memoryTotal = explode(" ", $memoryTotal);
$memoryTotal = $memoryTotal[0];
$memoryTotal *= 1024; // 将KiB转换为字节
}

// 空闲内存
if (count($statLineData) == 2 && trim($statLineData[0]) == "MemFree") {
$memoryFree = trim($statLineData[1]);
$memoryFree = explode(" ", $memoryFree);
$memoryFree = $memoryFree[0];
$memoryFree *= 1024; // 将KiB转换为字节
}
}
}
}
}

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');
}
}

// 内存使用情况:4.55 GiB / 23.91 GiB (19.013557664178%)
$memUsage = getServerMemoryUsage(false);
echo
sprintf("内存使用情况:%s / %s (%s%%)",
getNiceFileSize($memUsage["total"] - $memUsage["free"]),
getNiceFileSize($memUsage["total"]),
getServerMemoryUsage(true)
);

?>

函数getNiceFileSize()不是必需的。仅用于缩短以字节为单位的大小。

注意:如果您需要服务器负载(CPU使用率),我也编写了一个不错的函数来获取它:https://php.net/manual/en/function.sys-getloadavg.php#118673
jeff dot peck at snet dot 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)." 千字节";
else
echo
round($mem_usage/1048576,2)." 兆字节";

echo
"<br/>";
}
?>
[email protected]
14 年前
我可以确认此函数会触发垃圾回收。我有一个脚本在某个时刻超过了 128MB 的内存,并以致命错误结束。我感到困惑,因为脚本最初处理了一些大型文件,但从那时起内存负载应该很小,并且错误发生在最后。

这些大型文件是在一个专用的函数中处理的,我甚至在该函数内部将文件写入磁盘后,对保存文件的变量使用了 unset()。所以内存应该被清除两次,第一次在 unset() 调用之后,第二次在函数结束时。

为了调试内存使用情况,我在某些点调用了 memory_get_usage(true) 并回显了内存分配。仅仅在脚本中添加了一些回显,内存使用量从未超过 1MB 的开销(在当前文件大小之上),并且内存错误消失了。
[email protected]
20 年前
[由 danbrown AT php DOT net 编辑:作者的本意是仅在 PHP 4 < 4.3.2 中使用。]

我想指出,虽然 sandeepc at myrealbox dot com 提出的显示当前内存使用情况的想法很好,但通过 grep 管道传输整个进程列表可能不是一个好主意。更好的方法是仅选择我们感兴趣的进程

<?php
$pid
= getmypid();
error_log('MEMORY USAGE (% KB PID ): ' . `ps --pid $pid --no-headers -o%mem,rss,pid`);
?>

确实,这并不是很大的性能提升,但积少成多。
[email protected]
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 命令
MEMORY USAGE (% KB PID ): 0.8 12588 25087 -> 大约 12MB
2) 使用 memory_get_usage()
int(6041952) -> 大约 6MB
[email protected]
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 );
?>
[email protected]
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>';

}
?>
[email protected]
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;
}
}
}
?>
[email protected]
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