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;
}

a, b, creturn3IO d 也是局部變量,但是return前將它保存到了全局變量eunset( e['client'])時,並且沒有任何其他PHP變量仍然在引用d d 就會被釋放。
全局變量
在PHP中,有3類全局變量。
● 使用global關鍵詞聲明的變量
● 使用static關鍵詞聲明的類靜態變量、函數靜態變量
● PHP的超全局變量,包括GET _POST、$GLOBALS等
全局變量和對象,類靜態變量,保存在swoole_server對象上的變量不會被釋放。需要程序員自行處理這些變量和對象的銷燬工作。

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

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

● 在事件回調函數中需要特別注意非局部變量的array類型值,某些操作如 TestClass::array[]=string調TestClass:: string .= $data,可能會有內存泄漏,嚴重時可能發生爆內存。
解決方法
● 同步阻塞並且請求響應式無狀態的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;
}

clientreturn client是異步客戶端在執行connect時swoole引擎底層會增加一次引用計數,因此return時並不會銷燬
● 執行onReceive回調函數時進行了close或者服務器端主動關閉連接觸發onClose,這時底層會減少引用計數,$client纔會被銷燬

發佈了26 篇原創文章 · 獲贊 62 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章