I use Ratchet as a socket server for some browser-based game, and I noticed a very weird behaviour.
My application class implements WampServerInterface and I noticed that after 4-5 clients connect and disconnect (via autobahn.js) some memory (about 300KB) remains stuck. Then if another 7-8 clients connect and disconnect the memory usage will not increase. It will increase when 10-12 new clients connect and disconnect, so I have an impression that it reuses memory but still I have a fear that it could cause a memory leak, when many clients connect to the server.
Then I decided to do some testing, I made an application class that implements MessageComponentInterface (so that I can connect with the telnet). Here is the code that launches the server:
<?php
ini_set('display_errors', 'On');
require 'vendor/autoload.php';
require 'bootstrap.php';
use Ratchet\Server\IoServer;
use AsterMedia\Games\Socket;
$server = IoServer::factory(
new Socket(),
9090,
'127.0.0.1'
);
$server->run();
?>
My application class is very simple and it looks like this:
<?php
namespace AsterMedia\Games;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Symfony\Component\Console\Output\OutputInterface;
class Socket implements MessageComponentInterface {
public function onClose(ConnectionInterface $conn) {
echo "Client disconnected" . $this->getMemoryUsage() . PHP_EOL;
}
public function onError(ConnectionInterface $conn, \Exception $e) {
echo $e->getMessage() . PHP_EOL;
}
public function onOpen(ConnectionInterface $conn) {
echo "Client connected" . $this->getMemoryUsage() . PHP_EOL;
}
public function onMessage(ConnectionInterface $from, $msg) {
echo $msg . PHP_EOL;
}
private function getMemoryUsage() {
return sprintf('[Memory usage (currently) %dKB/ (max) %dKB]', round(memory_get_usage(true) / 1024), memory_get_peak_usage(true) / 1024);
}
}
Finally, I made a bash script that connects and disconnects in an endless loop:
while true
do
echo "connect"
exec 3<>/dev/tcp/127.0.0.1/9090
exec 3<&-
echo "disconnect"
sleep 1
done
After running the bash script, I noticed the same behavior - after a few cycles, the memory usage increases.
Is this issue related to Ratchet (or React) or this is simply PHP's issue? I forgot to mention that I use PHP 5.5.3 with GC enabled.
By default WampServer does not free Topics once they are empty. Ratchet v0.3.2 introduced a new feature to change this. Topic objects now have a property called autoDelete that if set to true will destroy the Topic once the number of subscribers has reached 0.
public function onSubscribe(ConnectionInterface $conn, $topic) {
$topic->autoDelete = true;
}
The reason the reference is held was originally a (poor) design decision. autoDelete, instead of automatically freeing the Topic, was implemented because the change caused backwards compatibility breaks and bug if user land code kept reference to Topics (assuming unique object by id).
By setting autoDelete to true you will eventually notice your memory consumption go down once the GC runs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With