用 vld 神器,来解疑一段诡异的php代码
今天公司技术群抛出一个问题。
for ($i = 0; $i < 1000000; $i++) { $array = ['a' => $i, 'b' => $i]; foreach ($array as $key => $val) { true && $array[$key] = trim($val); } if ($i % 10000 == 0) { $memory = round(memory_get_peak_usage(TRUE) / pow(1024, 2), 2); echo "$i $memory\n"; } }
开启opcache时,该运行代码内存会占用会越来越大。但删除行4的 true && 或 关闭 opcache 内存都是占用很小不会增大。在测试的PHP 5.4和7.0均存在。
可猜到,应该是变量没有被释放导致。为啥会这样呢?
只好拿出压箱底的神器—— vld,上次用也是第一次用是n年前了,差点忘记她的名字。
这是一个可以看php运行的opcode的php扩展,可以在找到php语言级别中一些迷惑。
看看
#1 opcache close, mem == 5 14 > JMPZ_EX ~10 <bool>, ->20 15 > SEND_VAR !3 16 DO_FCALL 1 $12 'trim' 17 ASSIGN_DIM $11 !1, !2 18 OP_DATA $12, $13 19 BOOL ~10 $11 20 > FREE ~10 #2 opcache open, mem ++ 5 13 SEND_VAR !3 14 DO_FCALL 1 $1 'trim' 15 ASSIGN_DIM $2 !1, !2 16 OP_DATA $1, $2 #3 opcache open & no and, mem== 5 13 SEND_VAR !3 14 DO_FCALL 1 $1 'trim' 15 ASSIGN_DIM !1, !2 16 OP_DATA $1, $2
对比上面看出(倒数第二列是 return )
内存的增加就在于ASSIGN_DIM 后有返回值,而且没有被释放。至于为啥没释放??我也布吉岛啊~
同时对比代码1、2可以看出,opcache确实也优化了不少代码。
发表评论