diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 3b120c388..5fec9f9bf 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -1439,6 +1439,18 @@ class Server{ } $this->config = new Config($this->dataPath . "pocketmine.yml", Config::YAML, []); + define('pocketmine\DEBUG', (int) $this->getProperty("debug.level", 1)); + + if(((int) ini_get('zend.assertions')) > 0 and ((bool) $this->getProperty("debug.assertions.warn-if-enabled", true)) !== false){ + $this->logger->warning("Debugging assertions are enabled, this may impact on performance. To disable them, set `zend.assertions = -1` in php.ini."); + } + + ini_set('assert.exception', '1'); + + if($this->logger instanceof MainLogger){ + $this->logger->setLogDebug(\pocketmine\DEBUG > 1); + } + $this->logger->info("Loading server properties..."); $this->properties = new Config($this->dataPath . "server.properties", Config::PROPERTIES, [ "motd" => "Minecraft: PE Server", @@ -1540,18 +1552,6 @@ class Server{ $this->setConfigInt("difficulty", 3); } - define('pocketmine\DEBUG', (int) $this->getProperty("debug.level", 1)); - - if(((int) ini_get('zend.assertions')) > 0 and ((bool) $this->getProperty("debug.assertions.warn-if-enabled", true)) !== false){ - $this->logger->warning("Debugging assertions are enabled, this may impact on performance. To disable them, set `zend.assertions = -1` in php.ini."); - } - - ini_set('assert.exception', '1'); - - if($this->logger instanceof MainLogger){ - $this->logger->setLogDebug(\pocketmine\DEBUG > 1); - } - if(\pocketmine\DEBUG >= 0){ @cli_set_process_title($this->getName() . " " . $this->getPocketMineVersion()); } diff --git a/src/pocketmine/resources/pocketmine.yml b/src/pocketmine/resources/pocketmine.yml index d8bc7d88c..6c81de581 100644 --- a/src/pocketmine/resources/pocketmine.yml +++ b/src/pocketmine/resources/pocketmine.yml @@ -37,6 +37,11 @@ memory: #This will stop the server when the limit is surpassed main-hard-limit: 1024 + #AsyncWorker threads' hard memory limit in megabytes. Set to 0 to disable + #This will stop the server if any worker exceeds this limit. + #NOTE: THIS LIMIT APPLIES PER WORKER, NOT TO THE WHOLE PROCESS. + async-worker-hard-limit: 1024 + #Period in ticks to check memory (default 1 second) check-rate: 20 diff --git a/src/pocketmine/scheduler/AsyncPool.php b/src/pocketmine/scheduler/AsyncPool.php index 6d13e3d6d..9a7e6ed65 100644 --- a/src/pocketmine/scheduler/AsyncPool.php +++ b/src/pocketmine/scheduler/AsyncPool.php @@ -47,9 +47,11 @@ class AsyncPool{ $this->server = $server; $this->size = $size; + $memoryLimit = (int) max(-1, (int) $this->server->getProperty("memory.async-worker-hard-limit", 1024)); + for($i = 0; $i < $this->size; ++$i){ $this->workerUsage[$i] = 0; - $this->workers[$i] = new AsyncWorker($this->server->getLogger(), $i + 1); + $this->workers[$i] = new AsyncWorker($this->server->getLogger(), $i + 1, $memoryLimit); $this->workers[$i]->setClassLoader($this->server->getLoader()); $this->workers[$i]->start(); } @@ -61,9 +63,12 @@ class AsyncPool{ public function increaseSize(int $newSize){ if($newSize > $this->size){ + + $memoryLimit = (int) max(-1, (int) $this->server->getProperty("memory.async-worker-hard-limit", 1024)); + for($i = $this->size; $i < $newSize; ++$i){ $this->workerUsage[$i] = 0; - $this->workers[$i] = new AsyncWorker($this->server->getLogger(), $i + 1); + $this->workers[$i] = new AsyncWorker($this->server->getLogger(), $i + 1, $memoryLimit); $this->workers[$i]->setClassLoader($this->server->getLoader()); $this->workers[$i]->start(); } diff --git a/src/pocketmine/scheduler/AsyncWorker.php b/src/pocketmine/scheduler/AsyncWorker.php index 7b8532feb..80608acda 100644 --- a/src/pocketmine/scheduler/AsyncWorker.php +++ b/src/pocketmine/scheduler/AsyncWorker.php @@ -31,17 +31,27 @@ class AsyncWorker extends Worker{ private $logger; private $id; - public function __construct(MainLogger $logger, int $id){ + /** @var int */ + private $memoryLimit; + + public function __construct(MainLogger $logger, int $id, int $memoryLimit){ $this->logger = $logger; $this->id = $id; + $this->memoryLimit = $memoryLimit; } public function run(){ $this->registerClassLoader(); $this->logger->registerStatic(); - gc_enable(); - ini_set("memory_limit", '-1'); + + if($this->memoryLimit > 0){ + ini_set('memory_limit', $this->memoryLimit . 'M'); + $this->logger->debug("Set memory limit to " . $this->memoryLimit . " MB"); + }else{ + ini_set('memory_limit', '-1'); + $this->logger->debug("No memory limit set"); + } global $store; $store = [];