php include时不会自动释放内存的场景,开发时要留意。

fushutech

在composer个别库中,会include配置文件,在调用时会重复include,并且不会释放内存,导致实际业务不复杂,但是循环之后内存占满进程被kill掉。分享一下这个过程,开发时要留意。

pinyin.php:

<?php

return [
    'key1' => 'value1',
];

demo.php:

<?php

$list = []; // 假设这里有10万条数据库记录要处理

foreach ($list as $item) {
    $pinyin = include('pinyin.php');

    unset($pinyin); // 变量内存释放了,但是include的那部分内存无法释放
}

这里就没办法主动释放内存,这种情况我在composer的拼音库(overtrue/pinyin)遇到过一次。

<?php

use Overtrue\Pinyin\Pinyin;

foreach ($db_list as $item) {
    $pinyin = Pinyin::sentence('你好,世界');
}

因为这里作者为了开发方便封装了过程,但是在循环引用时候其内部逻辑重复include,最终导致进程内存占满被kill掉

还有一种情况是:
PHPQuery库,不停的向一个变量追加string,但是并未释放,因为他使用的是静态类,所以在用完之后要调用phpquery的释放方法来释放内存。

jaeger/querylist 库因为引用的是PHPQuery,所以也存在这个问题。

477 1 2
1个评论

walkor

php为了高性能并不会每次释放变量都会将内存交还给操作系统,而是留着下次复用。业务不用调用unset去主动释放变量,因为临时变量函数或方法运行完毕会自动释放。

不断include并不会导致内存泄露问题。
Pinyin::sentence('你好,世界');本地经过10次-1000次测试也没出现内存泄露问题。

PHPQuery库因为没有测试代码并未测试。

另外webman有内存检测机制,如果某个进程内存增长到一定程度会自动reload对应进程释放内存,所以即使有内存泄露也不用担心。

  • fushutech 2024-07-23

    感谢作者大大认真的验证,希望大家都可以借鉴。

fushutech

220
积分
0
获赞数
0
粉丝数
2024-05-18 加入
×
🔝