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 '';
+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',