php 8.1中response对象不unset会持续占内存,需显式unset()或domdocument::clear()释放;内存是否真释放应以memory_get_usage(true)为准,而非memory_get_usage()。

PHP 8.1里response对象不unset会持续占内存
PHP没有Python那种隐式引用计数延迟释放的错觉,但爬虫中常见错误是把整个cURL响应、DOMDocument或解析后的数组长期挂在全局变量、静态属性或闭包里。只要变量还存在作用域外的引用,内存就不会归还给OS——哪怕脚本还在跑。
典型场景:static $cache = []; 里存了 curl_exec() 返回的 HTML 字符串,或用 DOMDocument::loadHTML() 解析后没调 unset($dom);更隐蔽的是在 foreach 中直接赋值引用(如 &$item),导致底层 zval 引用计数卡住。
- 每次
curl_exec()返回的字符串可能几 MB,叠加 100 次就几百 MB -
DOMDocument对象内部持有大量 C 层节点指针,仅unset($dom)不够,得配合$dom->clear()(PHP 8.1+ 支持) - 避免用
global或static缓存中间结果;改用函数局部变量 + 显式unset()
怎么确认内存真没释放?看 memory_get_usage(true) 而不是 memory_get_usage()
memory_get_usage() 返回的是 PHP 内部堆分配量,常被缓存和复用干扰;而 memory_get_usage(true) 返回的是向 OS 实际申请的内存页大小(即 RSS 近似值),这才是你该盯的数字。
实操建议:在循环抓取前后各打一次快照,比如:
echo "Before: " . memory_get_usage(true) . "\n"; $html = curl_exec($ch); $dom = new DOMDocument(); @$dom->loadHTML($html); // ... 解析逻辑 unset($html, $dom); // 必须显式 echo "After: " . memory_get_usage(true) . "\n";
如果 “After” 比 “Before” 高出 >2MB 且随循环稳定上涨,说明有泄漏。注意:PHP 8.1 的垃圾回收器(GC)默认启用,但只对循环引用生效,对普通变量生命周期无干预。
curl_close() 和 curl_reset() 的区别直接影响内存驻留
很多人以为 curl_close($ch) 就万事大吉,其实它只释放 cURL 句柄资源;若之前用过 curl_setopt($ch, CURLOPT_HEADERFUNCTION, ...) 或自定义写入回调,回调里若捕获了大字符串并存到闭包里,curl_close() 压根不管那部分。
- 高频请求建议复用
CurlHandle(PHP 8.0+)+curl_reset(),比反复curl_init()/curl_close()更省内存 - 绝对不要在
CURLOPT_WRITEFUNCTION回调中做array_push($GLOBALS['buffer'], $data)—— 这会让所有响应体字节累积进全局数组 - 用
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true)是安全的,但返回值必须立刻处理完并unset
DOMDocument 和 SimpleXML 解析后不清理的后果
PHP 8.1 中 DOMDocument 的内存开销远超字符串本身:每个节点都是独立 zval,树形结构导致引用链复杂。即使你 unset($dom),若之前调过 $dom->getElementsByTagName() 并把结果存为变量,那些 DOMNodeList 对象仍强引用着文档。
可靠做法:
- 解析完立即调
$dom->clear()(PHP 8.1 新增,清空所有节点但保留对象) - 再
unset($dom),确保 zval 引用计数归零 - 避免用
SimpleXML处理大 HTML:它底层也用 DOM,但 API 更易无意持有引用,比如$xml->children()返回的对象未被释放 - 小数据用正则(
preg_match_all())反而更轻量——前提是 HTML 结构足够规整
use (&$buffer),又把这个函数塞进某个队列对象里。这种泄漏不会报错,只会让 memory_get_usage(true) 每轮悄悄涨个几十 KB,跑几千次就崩。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











