swoole_server中内存管理机制

swoole_server启动后内存管理的底层原理与普通php-cli程序一致。具体请参考Zend VM内存管理方面的文章。

局部变量

在事件回调函数返回后,所有局部对象和变量会全部回收,不需要unset。如果变量是一个资源类型,那么对应的资源也会被PHP底层释放。

function test()
{
	$a = new Object;
	$b = fopen('/data/t.log', 'r+');
	$c = new swoole_client(SWOOLE_SYNC);
	$d = new swoole_client(SWOOLE_SYNC);
	global $e;
	$e['client'] = $d;
}

全局变量

在PHP中,有3类全局变量。

全局变量和对象,类静态变量,保存在swoole_server对象上的变量不会被释放。需要程序员自行处理这些变量和对象的销毁工作。

class Test
{
	static $array = array();
	static $string = '';
}

function onReceive($serv, $fd, $reactorId, $data)
{
	Test::$array[] = $fd;
	Test::$string .= $data;
}

解决方法

异步客户端

Swoole提供的异步客户端与普通的PHP变量不同,异步客户端在发起connect时底层会增加一次引用计数,在连接close时会减少引用计数。

包括swoole_clientswoole_mysqlswoole_redisswoole_http_client

function test()
{
	$client = new swoole_client(SWOOLE_TCP | SWOOLE_ASYNC);
	$client->on("connect", function($cli) {
		$cli->send("hello world\n");
	});
	$client->on("receive", function($cli, $data){
		echo "Received: ".$data."\n";
		$cli->close();
	});
	$client->on("error", function($cli){
		echo "Connect failed\n";
	});
	$client->on("close", function($cli){
		echo "Connection close\n";
	});
	$client->connect('127.0.0.1', 9501);
	return;
}