From d64d5f081c057ff6ead582f88af3a1db92046100 Mon Sep 17 00:00:00 2001 From: Clemens Schwaighofer Date: Thu, 2 Jun 2022 16:26:55 +0900 Subject: [PATCH] Add Class for Memory Usage tracking --- 4dev/tests/CoreLibsDebugMemoryUsageTest.php | 119 ++++++++++++++++++ www/admin/class_test.memoryusage.php | 91 ++++++++++++++ www/lib/CoreLibs/Debug/MemoryUsage.php | 129 ++++++++++++++++++++ www/vendor/composer/autoload_classmap.php | 1 + www/vendor/composer/autoload_static.php | 1 + 5 files changed, 341 insertions(+) create mode 100644 4dev/tests/CoreLibsDebugMemoryUsageTest.php create mode 100644 www/admin/class_test.memoryusage.php create mode 100644 www/lib/CoreLibs/Debug/MemoryUsage.php diff --git a/4dev/tests/CoreLibsDebugMemoryUsageTest.php b/4dev/tests/CoreLibsDebugMemoryUsageTest.php new file mode 100644 index 00000000..7b8e0205 --- /dev/null +++ b/4dev/tests/CoreLibsDebugMemoryUsageTest.php @@ -0,0 +1,119 @@ + '/^[\w\s_-]+$/', + 'peak' => '/^\d+$/', + 'usage' => '/^\d+$/', + 'start' => '/^\d+$/', + 'last' => '/^\d+$/', + 'set' => '/^\d+$/', + ]; + // 0: prefix + // 1: raw flag + // 2: set flags array + // 3: array output expected (as regex) + // 4: string output expected (as regex) + return [ + 'test normal' => [ + 'test', + null, + [], + $regex_array, + $regex_raw_off, + ] + ]; + } + + /** + * Undocumented function + * + * @cover ::resetMemory + * @cover ::debugMemoryFlag + * @cover ::setStartMemory + * @cover ::setMemory + * @cover ::memoryUsage + * @cover ::printMemoryUsage + * @dataProvider memoryUsageProvider + * @testdox memoryUsage with $prefix, raw memory $raw [$_dataName] + * + * @param string $prefix + * @param bool|null $raw + * @param array $set_flags + * @param array $expected_array + * @param string $expected_string + * @return void + */ + public function testMemoryUsage( + string $prefix, + ?bool $raw, + array $settings, + array $expected_array, + string $expected_string + ): void { + // always reeset to null + MemoryUsage::resetMemory(); + MemoryUsage::debugMemoryFlag(true); + MemoryUsage::setStartMemory(); + MemoryUsage::setMemory(); + // run collector + $memory = MemoryUsage::memoryUsage($prefix); + if ($raw === null) { + $string = MemoryUsage::printMemoryUsage($memory); + } else { + $string = MemoryUsage::printMemoryUsage($memory, $raw); + } + + // expected_array for each + foreach ($expected_array as $name => $regex) { + $this->assertMatchesRegularExpression( + $regex, + (string)$memory[$name], + 'assert memory usage array ' . $name + ); + } + + // regex match string + $this->assertMatchesRegularExpression( + $expected_string, + $string, + 'assert memory usage string as regex' + ); + + // TODO additional tests with use more memory and check diff matching + // TODO reset memory usage test + } +} + +// __END__ diff --git a/www/admin/class_test.memoryusage.php b/www/admin/class_test.memoryusage.php new file mode 100644 index 00000000..f4971f76 --- /dev/null +++ b/www/admin/class_test.memoryusage.php @@ -0,0 +1,91 @@ + BASE . LOG, + 'file_id' => $LOG_FILE_ID, + // add file date + 'print_file_date' => true, + // set debug and print flags + 'debug_all' => $DEBUG_ALL ?? false, + 'echo_all' => $ECHO_ALL ?? false, + 'print_all' => $PRINT_ALL ?? false, +]); + +$PAGE_NAME = 'TEST CLASS: MEMORY USAGE'; +print ""; +print "" . $PAGE_NAME . ""; +print ""; +print '
Class Test Master
'; +print '

' . $PAGE_NAME . '

'; + +MemoryUsage::debugMemoryFlag(true); +print "Debug Flag: " . Support::printBool(MemoryUsage::debugMemoryFlag()) . "
"; +MemoryUsage::setStartMemory(); +MemoryUsage::setMemory(); +$data = MemoryUsage::memoryUsage('first run'); +print "Memory usage 1 array: " . Support::printAr($data) . "
"; +print "Memory usage 1 string: " . MemoryUsage::printMemoryUsage($data) . "
"; +print "Memory usage 1 string raw: " . MemoryUsage::printMemoryUsage($data, true) . "
"; +$var = 'foo'; +$out = ''; +for ($i = 1; $i <= 100; $i++) { + $out .= $var; +} +$data = MemoryUsage::memoryUsage('second run'); +print "Memory usage 2 array: " . Support::printAr($data) . "
"; +print "Memory usage 2 string: " . MemoryUsage::printMemoryUsage($data) . "
"; +print "Memory usage 2 string raw: " . MemoryUsage::printMemoryUsage($data, true) . "
"; +MemoryUsage::setMemory(); +$var = 'foasdfasdfasdfasdfasdfo'; +$out = ''; +for ($i = 1; $i <= 10000; $i++) { + $out .= $var; +} +$data = MemoryUsage::memoryUsage('third run'); +print "Memory usage 3 array: " . Support::printAr($data) . "
"; +print "Memory usage 3 string: " . MemoryUsage::printMemoryUsage($data) . "
"; +print "Memory usage 3 string raw: " . MemoryUsage::printMemoryUsage($data, true) . "
"; +$var = 'foasdfasdfasdasdfasdfasdfadfadfasdfasdfo'; +$out = ''; +for ($i = 1; $i <= 100000; $i++) { + $out .= $var; +} +$data = MemoryUsage::memoryUsage('forth run'); +print "Memory usage 4 array: " . Support::printAr($data) . "
"; +print "Memory usage 4 string: " . MemoryUsage::printMemoryUsage($data) . "
"; +print "Memory usage 4 string raw: " . MemoryUsage::printMemoryUsage($data, true) . "
"; + +// error message +print $log->printErrorMsg(); + +print ""; + +// __END__ diff --git a/www/lib/CoreLibs/Debug/MemoryUsage.php b/www/lib/CoreLibs/Debug/MemoryUsage.php new file mode 100644 index 00000000..f6090b27 --- /dev/null +++ b/www/lib/CoreLibs/Debug/MemoryUsage.php @@ -0,0 +1,129 @@ + return array + */ + public static function memoryUsage(string $prefix): array + { + // skip if DEBUG is off + if (self::$debug_memory === false) { + return []; + } + if (empty(self::$start_memory)) { + self::$start_memory = memory_get_usage(); + } + $memory_usage = memory_get_usage(); + $data = [ + 'prefix' => $prefix, + 'peak' => memory_get_peak_usage(), + 'usage' => $memory_usage, + 'start' => $memory_usage - self::$start_memory, + 'last' => $memory_usage - self::$previous_memory, + 'set' => $memory_usage - self::$set_memory + ]; + self::$previous_memory = $memory_usage; + return $data; + } + + /** + * returns a human readable output from the memoryUsage function + * can be used for logging purpose + * + * @param array $data Data array from memoryUsage + * @param bool $raw Flag to shaw unconverted memory numbers + * @return string Return debug string with memory usage + */ + public static function printMemoryUsage(array $data, bool $raw = false): string + { + return + '[' . $data['prefix'] . '] Peak/Curr/Change: ' + . Byte::humanReadableByteFormat($data['peak']) + . '/' + . Byte::humanReadableByteFormat($data['usage']) + // . ($raw === true ? ' [' . $data['usage'] . ']' : '') + . '/Since Start: ' + . Byte::humanReadableByteFormat($data['start']) + . ($raw === true ? ' [' . $data['start'] . ']' : '') + . ' | Since Last: ' + . Byte::humanReadableByteFormat($data['last']) + . ($raw === true ? ' [' . $data['last'] . ']' : '') + . ' | Since Set: ' + . Byte::humanReadableByteFormat($data['set']) + . ($raw === true ? ' [' . $data['set'] . ']' : ''); + } +} + +// __END__ diff --git a/www/vendor/composer/autoload_classmap.php b/www/vendor/composer/autoload_classmap.php index 37416b44..91a57e0c 100644 --- a/www/vendor/composer/autoload_classmap.php +++ b/www/vendor/composer/autoload_classmap.php @@ -37,6 +37,7 @@ return array( 'CoreLibs\\DB\\SQL\\SqlInterface\\SqlFunctions' => $baseDir . '/lib/CoreLibs/DB/SQL/SqlInterface/SqlFunctions.php', 'CoreLibs\\Debug\\FileWriter' => $baseDir . '/lib/CoreLibs/Debug/FileWriter.php', 'CoreLibs\\Debug\\Logging' => $baseDir . '/lib/CoreLibs/Debug/Logging.php', + 'CoreLibs\\Debug\\MemoryUsage' => $baseDir . '/lib/CoreLibs/Debug/MemoryUsage.php', 'CoreLibs\\Debug\\RunningTime' => $baseDir . '/lib/CoreLibs/Debug/RunningTime.php', 'CoreLibs\\Debug\\Support' => $baseDir . '/lib/CoreLibs/Debug/Support.php', 'CoreLibs\\Get\\ReadEnvFile' => $baseDir . '/lib/CoreLibs/Get/ReadEnvFile.php', diff --git a/www/vendor/composer/autoload_static.php b/www/vendor/composer/autoload_static.php index 162ef581..9ec986ca 100644 --- a/www/vendor/composer/autoload_static.php +++ b/www/vendor/composer/autoload_static.php @@ -102,6 +102,7 @@ class ComposerStaticInit10fe8fe2ec4017b8644d2b64bcf398b9 'CoreLibs\\DB\\SQL\\SqlInterface\\SqlFunctions' => __DIR__ . '/../..' . '/lib/CoreLibs/DB/SQL/SqlInterface/SqlFunctions.php', 'CoreLibs\\Debug\\FileWriter' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/FileWriter.php', 'CoreLibs\\Debug\\Logging' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/Logging.php', + 'CoreLibs\\Debug\\MemoryUsage' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/MemoryUsage.php', 'CoreLibs\\Debug\\RunningTime' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/RunningTime.php', 'CoreLibs\\Debug\\Support' => __DIR__ . '/../..' . '/lib/CoreLibs/Debug/Support.php', 'CoreLibs\\Get\\ReadEnvFile' => __DIR__ . '/../..' . '/lib/CoreLibs/Get/ReadEnvFile.php',