首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

解決 phpQuery 內存洩漏:靜態 $documents 陣列導致的 OOM 問題

     編輯:PHP 相關知識

問題現象

使用 phpQuery 批量解析網頁時,內存迅速飆升(>1GB),甚至觸發 OOM。原因:phpQuery 內部靜態屬性 $documents 保存所有歷史 DOMDocumentWrapper 實例,未主動釋放。

源碼定位

// phpQuery.php 內部
static public $documents = [];
public static function createDocumentWrapper($doc) {
    $wrapper = new DOMDocumentWrapper($doc);
    self::$documents[$wrapper->id] = $wrapper; // 每次解析添加一個,永不清理
    return $wrapper;
}

一行代碼修復

while (true) {
    phpQuery::newDocumentFile($htmlFile);
    // 處理頁面元素...
    
    // 關鍵:每次解析完清空靜態緩存
    phpQuery::$documents = [];
    
    echo memory_get_usage() . "\n"; // 內存穩定
}

最佳實踐封裝

function parseWithPhpQuery($html) {
    phpQuery::newDocumentHTML($html);
    try {
        // 業務解析邏輯
        $data = pq('.target')->html();
        return $data;
    } finally {
        // 確保異常時也能清理
        phpQuery::$documents = [];
        phpQuery::unloadDocuments(); // 部分版本提供
    }
}

替代方案

  • Symfony DomCrawler:現代、無狀態、內存友好,配合 CssSelector 組件。
  • Masterminds/HTML5:HTML5 解析器,支援選擇器。
  • 簡單場景用 DOMDocument + DOMXPath:原生擴展,無第三方依賴。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved