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類全局變量。
● 使用global關鍵詞聲明的變量
● 使用static關鍵詞聲明的類靜態變量、函數靜態變量
● PHP的超全局變量,包括
全局變量和對象,類靜態變量,保存在swoole_server對象上的變量不會被釋放。需要程序員自行處理這些變量和對象的銷燬工作。
class Test
{
static $array = array();
static $string = '';
}
function onReceive($serv, $fd, $reactorId, $data)
{
Test::$array[] = $fd;
Test::$string .= $data;
}
● 在事件回調函數中需要特別注意非局部變量的array類型值,某些操作如 TestClass::
解決方法
● 同步阻塞並且請求響應式無狀態的Server程序可以設置max_request,當Worker進程/Task進程結束運行時或達到任務上限後進程自動退出。該進程的所有變量/對象/資源均會被釋放回收。
● 程序內在onClose或設置定時器及時使用unset清理變量,回收資源
異步客戶端
Swoole提供的異步客戶端與普通的PHP變量不同,異步客戶端在發起connect時底層會增加一次引用計數,在連接close時會減少引用計數。
包括swoole_client、swoole_mysql、swoole_redis、swoole_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;
}
●
● 執行onReceive回調函數時進行了close或者服務器端主動關閉連接觸發onClose,這時底層會減少引用計數,$client纔會被銷燬