38

有没有办法通过 php(使用 linux 命令的宽度输出)来了解服务器(linux 发行版)中的可用内存?

编辑:抱歉,目标是了解特定服务器的服务器/虚拟机中可用的内存(即使该内存是共享的)。

4

9 回答 9

44

如果您知道这段代码只能在 Linux 下运行,您可以使用特殊/proc/meminfo文件来获取有关系统虚拟内存子系统的信息。该文件具有如下形式:

MemTotal:       255908 kB
MemFree:         69936 kB
Buffers:         15812 kB
Cached:         115124 kB
SwapCached:          0 kB
Active:          92700 kB
Inactive:        63792 kB
...

第一行,MemTotal: ...,包含机器中物理 RAM 的数量,减去内核为自己使用而保留的空间。这是我所知道的获得 Linux 系统上可用内存的简单报告的最佳方式。您应该能够通过类似以下代码的方式提取它:

<?php
  $fh = fopen('/proc/meminfo','r');
  $mem = 0;
  while ($line = fgets($fh)) {
    $pieces = array();
    if (preg_match('/^MemTotal:\s+(\d+)\skB$/', $line, $pieces)) {
      $mem = $pieces[1];
      break;
    }
  }
  fclose($fh);

  echo "$mem kB RAM found"; ?>

(请注意:此代码可能需要针对您的环境进行一些调整。)

于 2009-09-21T16:37:47.963 回答
39

使用/proc/meminfo并将所有内容放入数组很简单:

<?php

function getSystemMemInfo() 
{       
    $data = explode("\n", file_get_contents("/proc/meminfo"));
    $meminfo = array();
    foreach ($data as $line) {
        list($key, $val) = explode(":", $line);
        $meminfo[$key] = trim($val);
    }
    return $meminfo;
}

?>

var_dump( getSystemMemInfo() );

array(43) {
  ["MemTotal"]=>
  string(10) "2060700 kB"
  ["MemFree"]=>
  string(9) "277344 kB"
  ["Buffers"]=>
  string(8) "92200 kB"
  ["Cached"]=>
  string(9) "650544 kB"
  ["SwapCached"]=>
  string(8) "73592 kB"
  ["Active"]=>
  string(9) "995988 kB"
  ...
于 2009-09-21T17:04:57.770 回答
6

Linux 命令可以使用PHP中的exec函数运行。这是有效的并且可以完成工作(如果目标是获取内存)。

试试下面的代码:

<?php
  exec("free -mtl", $output);
  print_r($output);
?>
于 2013-11-22T11:52:03.417 回答
3

小而整洁的功能,以获取与其键关联的所有值。

$contents = file_get_contents('/proc/meminfo');
preg_match_all('/(\w+):\s+(\d+)\s/', $contents, $matches);
$info = array_combine($matches[1], $matches[2]);

// $info['MemTotal'] = "2047442"
于 2019-12-07T06:58:22.077 回答
2

我认为如果没有专门编写的 PHP 扩展,您将无法访问主机服务器内存信息。PHP 核心库不允许(可能出于安全原因)访问扩展内存信息。

但是,如果您的脚本可以访问,/proc/meminfo那么您可以查询该特殊文件并获取您需要的信息。在 Windows 上(尽管您没有要求它),我们可以使用com_dotnetPHP 扩展通过 COM 查询 Windows 框架。

getSystemMemoryInfo无论您是否在 Linux/Windows 服务器上运行脚本,您都可以在下面找到我的返回信息。这wmiWBemLocatorQuery只是一个辅助功能。

function wmiWBemLocatorQuery( $query ) {
    if ( class_exists( '\\COM' ) ) {
        try {
            $WbemLocator = new \COM( "WbemScripting.SWbemLocator" );
            $WbemServices = $WbemLocator->ConnectServer( '127.0.0.1', 'root\CIMV2' );
            $WbemServices->Security_->ImpersonationLevel = 3;
            // use wbemtest tool to query all classes for namespace root\cimv2
            return $WbemServices->ExecQuery( $query );
        } catch ( \com_exception $e ) {
            echo $e->getMessage();
        }
    } elseif ( ! extension_loaded( 'com_dotnet' ) )
        trigger_error( 'It seems that the COM is not enabled in your php.ini', E_USER_WARNING );
    else {
        $err = error_get_last();
        trigger_error( $err['message'], E_USER_WARNING );
    }

    return false;
}

// _dir_in_allowed_path this is your function to detect if a file is withing the allowed path (see the open_basedir PHP directive)
function getSystemMemoryInfo( $output_key = '' ) {
    $keys = array( 'MemTotal', 'MemFree', 'MemAvailable', 'SwapTotal', 'SwapFree' );
    $result = array();

    try {
        // LINUX
        if ( ! isWin() ) {
            $proc_dir = '/proc/';
            $data = _dir_in_allowed_path( $proc_dir ) ? @file( $proc_dir . 'meminfo' ) : false;
            if ( is_array( $data ) )
                foreach ( $data as $d ) {
                    if ( 0 == strlen( trim( $d ) ) )
                        continue;
                    $d = preg_split( '/:/', $d );
                    $key = trim( $d[0] );
                    if ( ! in_array( $key, $keys ) )
                        continue;
                    $value = 1000 * floatval( trim( str_replace( ' kB', '', $d[1] ) ) );
                    $result[$key] = $value;
                }
        } else      // WINDOWS
        {
            $wmi_found = false;
            if ( $wmi_query = wmiWBemLocatorQuery( 
                "SELECT FreePhysicalMemory,FreeVirtualMemory,TotalSwapSpaceSize,TotalVirtualMemorySize,TotalVisibleMemorySize FROM Win32_OperatingSystem" ) ) {
                foreach ( $wmi_query as $r ) {
                    $result['MemFree'] = $r->FreePhysicalMemory * 1024;
                    $result['MemAvailable'] = $r->FreeVirtualMemory * 1024;
                    $result['SwapFree'] = $r->TotalSwapSpaceSize * 1024;
                    $result['SwapTotal'] = $r->TotalVirtualMemorySize * 1024;
                    $result['MemTotal'] = $r->TotalVisibleMemorySize * 1024;
                    $wmi_found = true;
                }
            }
            // TODO a backup implementation using the $_SERVER array
        }
    } catch ( Exception $e ) {
        echo $e->getMessage();
    }
    return empty( $output_key ) || ! isset( $result[$output_key] ) ? $result : $result[$output_key];
}

8GB RAM 系统上的示例

print_r(getSystemMemoryInfo());

输出

Array
(
    [MemTotal] => 8102684000
    [MemFree] => 2894508000
    [MemAvailable] => 4569396000
    [SwapTotal] => 4194300000
    [SwapFree] => 4194300000
)

如果您想了解每个字段代表的内容,请阅读更多内容

于 2016-03-04T10:12:41.397 回答
1

值得注意的是,在 Windows 中,可以通过执行和解析 shell 命令的输出来获取这些信息(以及更多信息):systeminfo

于 2014-05-31T06:25:35.340 回答
0

// 助手

/**
 * @return array|null
 */
protected function getSystemMemInfo()
{
    $meminfo = @file_get_contents("/proc/meminfo");
    if ($meminfo) {
        $data = explode("\n", $meminfo);
        $meminfo = [];
        foreach ($data as $line) {
            if( strpos( $line, ':' ) !== false ) {
                list($key, $val) = explode(":", $line);
                $val = trim($val);
                $val = preg_replace('/ kB$/', '', $val);
                if (is_numeric($val)) {
                    $val = intval($val);
                }
                $meminfo[$key] = $val;
            }
        }
        return $meminfo;
    }
    return  null;
}

// example call to check health
public function check() {
    $memInfo = $this->getSystemMemInfo();
    if ($memInfo) {
        $totalMemory = $memInfo['MemTotal'];
        $freeMemory = $memInfo['MemFree'];
        $swapTotalMemory = $memInfo['SwapTotal'];
        $swapFreeMemory = $memInfo['SwapFree'];
        if (($totalMemory / 100.0) * 30.0 > $freeMemory) {
            if (($swapTotalMemory / 100.0) * 50.0 > $swapFreeMemory) {
                return new Failure('Less than 30% free memory and less than 50% free swap space');
            }
            return new Warning('Less than 30% free memory');
        }
    }
    return new Success('ok');
}
于 2017-07-31T11:42:45.477 回答
0

exec("grep MemTotal /proc/meminfo", $aryMem); $aryMem[0] 的总内存减去内核使用量。

于 2021-12-07T20:30:27.743 回答
-1

我不记得曾经见过这样的函数——实际上,它超出了 PHP 的用途。

即使有这样的功能,它也可能会以特定于底层操作系统的方式实现,并且可能无法在 Linux 和 Windows 上运行(请参阅sys_getloadavg此类示例)

于 2009-09-21T16:23:26.497 回答