Revert "Added capability to dump AsyncWorker memory"

This reverts commit eb4594348b6fe4f8af83d5fd386f393956f7b561.

This is far too unstable with more than one worker thread.
This commit is contained in:
Dylan K. Taylor 2017-08-22 20:46:20 +01:00
parent eb4594348b
commit d1852834de
3 changed files with 14 additions and 122 deletions

View File

@ -25,9 +25,7 @@ namespace pocketmine;
use pocketmine\event\server\LowMemoryEvent;
use pocketmine\event\Timings;
use pocketmine\scheduler\DumpWorkerMemoryTask;
use pocketmine\scheduler\GarbageCollectionTask;
use pocketmine\utils\MainLogger;
use pocketmine\utils\Utils;
class MemoryManager{
@ -263,25 +261,6 @@ class MemoryManager{
* @param int $maxStringSize
*/
public function dumpServerMemory(string $outputFolder, int $maxNesting, int $maxStringSize){
MainLogger::getLogger()->notice("[Dump] After the memory dump is done, the server might crash");
self::dumpMemory($this->server, $this->server->getLoader(), $outputFolder, $maxNesting, $maxStringSize);
$scheduler = $this->server->getScheduler();
for($i = 0, $size = $scheduler->getAsyncTaskPoolSize(); $i < $size; ++$i){
$scheduler->scheduleAsyncTaskToWorker(new DumpWorkerMemoryTask($outputFolder, $maxNesting, $maxStringSize), $i);
}
}
/**
* Static memory dumper accessible from any thread.
*
* @param mixed $startingObject
* @param \ClassLoader $loader
* @param string $outputFolder
* @param int $maxNesting
* @param int $maxStringSize
*/
public static function dumpMemory($startingObject, \ClassLoader $loader, string $outputFolder, int $maxNesting, int $maxStringSize){
$hardLimit = ini_get('memory_limit');
ini_set('memory_limit', '-1');
gc_disable();
@ -290,8 +269,12 @@ class MemoryManager{
mkdir($outputFolder, 0777, true);
}
$this->server->getLogger()->notice("[Dump] After the memory dump is done, the server might crash");
$obData = fopen($outputFolder . "/objects.js", "wb+");
$staticProperties = [];
$data = [];
$objects = [];
@ -300,9 +283,8 @@ class MemoryManager{
$instanceCounts = [];
$staticProperties = [];
$staticCount = 0;
foreach($loader->getClasses() as $className){
foreach($this->server->getLoader()->getClasses() as $className){
$reflection = new \ReflectionClass($className);
$staticProperties[$className] = [];
foreach($reflection->getProperties() as $property){
@ -315,7 +297,7 @@ class MemoryManager{
}
$staticCount++;
self::continueDump($property->getValue(), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
$this->continueDump($property->getValue(), $staticProperties[$className][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
}
if(count($staticProperties[$className]) === 0){
@ -323,37 +305,9 @@ class MemoryManager{
}
}
file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
MainLogger::getLogger()->info("[Dump] Wrote $staticCount static properties");
echo "[Dump] Wrote $staticCount static properties\n";
$globalVariables = [];
$ignoredGlobals = [
'GLOBALS' => true,
'_SERVER' => true,
'_REQUEST' => true,
'_POST' => true,
'_GET' => true,
'_FILES' => true,
'_ENV' => true,
'_COOKIE' => true,
'_SESSION' => true
];
$globalCount = 0;
foreach($GLOBALS as $varName => $value){
if(isset($ignoredGlobals[$varName])){
continue;
}
$globalCount++;
self::continueDump($value, $globalVariables[$varName], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
}
file_put_contents($outputFolder . "/globalVariables.js", json_encode($globalVariables, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
MainLogger::getLogger()->info("[Dump] Wrote $globalCount global variables");
self::continueDump($startingObject, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize);
$this->continueDump($this->server, $data, $objects, $refCounts, 0, $maxNesting, $maxStringSize);
do{
$continue = false;
@ -395,24 +349,25 @@ class MemoryManager{
if(!$property->isPublic()){
$property->setAccessible(true);
}
self::continueDump($property->getValue($object), $info["properties"][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
$this->continueDump($property->getValue($object), $info["properties"][$property->getName()], $objects, $refCounts, 0, $maxNesting, $maxStringSize);
}
fwrite($obData, "$hash@$className: " . json_encode($info, JSON_UNESCAPED_SLASHES) . "\n");
}
MainLogger::getLogger()->info("[Dump] Wrote " . count($objects) . " objects");
echo "[Dump] Wrote " . count($objects) . " objects\n";
}while($continue);
fclose($obData);
file_put_contents($outputFolder . "/staticProperties.js", json_encode($staticProperties, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
file_put_contents($outputFolder . "/serverEntry.js", json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
file_put_contents($outputFolder . "/referenceCounts.js", json_encode($refCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
arsort($instanceCounts, SORT_NUMERIC);
file_put_contents($outputFolder . "/instanceCounts.js", json_encode($instanceCounts, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
MainLogger::getLogger()->info("[Dump] Finished!");
echo "[Dump] Finished!\n";
ini_set('memory_limit', $hardLimit);
gc_enable();
@ -427,7 +382,7 @@ class MemoryManager{
* @param int $maxNesting
* @param int $maxStringSize
*/
private static function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){
private function continueDump($from, &$data, array &$objects, array &$refCounts, int $recursion, int $maxNesting, int $maxStringSize){
if($maxNesting <= 0){
$data = "(error) NESTING LIMIT REACHED";
return;
@ -451,7 +406,7 @@ class MemoryManager{
}
$data = [];
foreach($from as $key => $value){
self::continueDump($value, $data[$key], $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize);
$this->continueDump($value, $data[$key], $objects, $refCounts, $recursion + 1, $maxNesting, $maxStringSize);
}
}elseif(is_string($from)){
$data = "(string) len(". strlen($from) .") " . substr(Utils::printable($from), 0, $maxStringSize);

View File

@ -64,8 +64,4 @@ class AsyncWorker extends Worker{
public function getThreadName() : string{
return "Asynchronous Worker #" . $this->id;
}
public function getAsyncWorkerId() : int{
return $this->id;
}
}

View File

@ -1,59 +0,0 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
declare(strict_types=1);
namespace pocketmine\scheduler;
use pocketmine\MemoryManager;
/**
* Task used to dump memory from AsyncWorkers
*/
class DumpWorkerMemoryTask extends AsyncTask{
/** @var string */
private $outputFolder;
/** @var int */
private $maxNesting;
/** @var int */
private $maxStringSize;
/**
* @param string $outputFolder
* @param int $maxNesting
* @param int $maxStringSize
*/
public function __construct(string $outputFolder, int $maxNesting, int $maxStringSize){
$this->outputFolder = $outputFolder;
$this->maxNesting = $maxNesting;
$this->maxStringSize = $maxStringSize;
}
public function onRun(){
MemoryManager::dumpMemory(
$this->worker,
$this->worker->getClassLoader(),
$this->outputFolder . DIRECTORY_SEPARATOR . "AsyncWorker#" . $this->worker->getAsyncWorkerId(),
$this->maxNesting,
$this->maxStringSize
);
}
}