![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/dev/tests/integration/framework/Magento/TestFramework/Helper/ |
<?php /** * Helper for determining system memory usage * * Uses OS tools to provide accurate information about factual memory consumption. * The PHP standard functions may return incorrect information because the process itself may have leaks. * * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\TestFramework\Helper; /** * Integration Test Framework memory management logic. */ class Memory { /** * Prefixes to specify unit of measure for memory amount * * Warning: it is important to maintain the exact order of letters in this literal, * as it is used to convert string with units to bytes */ const MEMORY_UNITS = 'BKMGTPE'; /** * @var \Magento\Framework\Shell */ private $_shell; /** * Inject dependencies * * @param \Magento\Framework\Shell $shell */ public function __construct(\Magento\Framework\Shell $shell) { $this->_shell = $shell; } /** * Retrieve the effective memory usage of the current process * * Function memory_get_usage() cannot be used because of the bug * * @link https://bugs.php.net/bug.php?id=62467 * @return int Memory usage in bytes */ public function getRealMemoryUsage() { $pid = getmypid(); try { // fall back to the Unix command line $result = $this->_getUnixProcessMemoryUsage($pid); } catch (\Magento\Framework\Exception\LocalizedException $e) { // try to use the Windows command line // some ports of Unix commands on Windows, such as MinGW, have limited capabilities and cannot be used $result = $this->_getWinProcessMemoryUsage($pid); } return $result; } /** * Retrieve the current process' memory usage using Unix command line interface * * @link http://linux.die.net/man/1/ps * @param int $pid * @return int Memory usage in bytes */ protected function _getUnixProcessMemoryUsage($pid) { // RSS - resident set size, the non-swapped physical memory $command = 'ps --pid %s --format rss --no-headers'; if ($this->isMacOS()) { $command = 'ps -p %s -o rss='; } $output = $this->_shell->execute($command, [$pid]); $result = $output . 'k'; // kilobytes return self::convertToBytes($result); } /** * Retrieve the current process' memory usage using Windows command line interface * * @link http://technet.microsoft.com/en-us/library/bb491010.aspx * @param int $pid * @return int Memory usage in bytes */ protected function _getWinProcessMemoryUsage($pid) { $output = $this->_shell->execute('tasklist.exe /fi %s /fo CSV /nh', ["PID eq {$pid}"]); $arr = str_getcsv($output); $memory = $arr[4]; return self::convertToBytes($memory); } /** * Convert a number optionally followed by the unit symbol (B, K, M, G, etc.) to bytes * * @param string $number String representation of a number * @return int * @throws \InvalidArgumentException * @throws \OutOfBoundsException * phpcs:disable Magento2.Functions.StaticFunction */ public static function convertToBytes($number) { // phpcs:enable Magento2.Functions.StaticFunction if (!preg_match('/^(.*\d)\h*(\D)$/', $number, $matches)) { throw new \InvalidArgumentException("Number format '{$number}' is not recognized."); } $unitSymbol = strtoupper($matches[2]); if (false === strpos(self::MEMORY_UNITS, $unitSymbol)) { throw new \InvalidArgumentException("The number '{$number}' has an unrecognized unit: '{$unitSymbol}'."); } $result = self::_convertToNumber($matches[1]); $pow = $unitSymbol ? strpos(self::MEMORY_UNITS, $unitSymbol) : 0; $is32Bit = PHP_INT_SIZE == 4; if ($is32Bit && $pow >= 4) { throw new \OutOfBoundsException("A 32-bit system is unable to process such a number."); } if ($unitSymbol) { $result *= pow(1024, $pow); } return (int)$result; } /** * Remove non-numeric characters in the string to cast it to a numeric value * * Incoming number can be presented in arbitrary format that depends on locale. We don't possess locale information. * So the best can be done is to treat number as an integer and eliminate delimiters. * Method will not behave correctly with non-integer numbers for the following reason: * - if value has more than one delimiter, such as in French notation: "1 234,56" -- then we can infer decimal part * - but the value has only one delimiter, such as "234,56", then it is impossible to know whether it is decimal * separator or not. Only knowing the right format would allow this. * * @param string $number * @return string * @throws \InvalidArgumentException * phpcs:disable Magento2.Functions.StaticFunction */ protected static function _convertToNumber($number) { // phpcs:enable Magento2.Functions.StaticFunction preg_match_all('/(\D+)/', $number, $matches); if (count(array_unique($matches[0])) > 1) { throw new \InvalidArgumentException( "The number '{$number}' seems to have decimal part. Only integer numbers are supported." ); } return preg_replace('/\D+/', '', $number); } /** * Whether the operating system belongs to the Mac family * * @link http://php.net/manual/en/function.php-uname.php * @return boolean * phpcs:disable Magento2.Functions.StaticFunction */ public static function isMacOs() { // phpcs:enable Magento2.Functions.StaticFunction return strtoupper(PHP_OS) === 'DARWIN'; } }