性能专题 - 内存峰值 ¶
作者:KK
发表日期:2016.10.14
要点速读 ¶
新增变量或有新的运算时一般都会累加内存峰值,但unset变量后不会降低峰值,再新增变量,会利用一些旧变量空出的空间,所以峰值会增加得不明显
当一个进程启动后,进程可以向系统申请分配内存,比如接下来一个变量要占16B容量的话,就要申请足够的容量来装这个变量了
所以PHP在运行过程中根据程序计算的需要,不断地按需求情况向系统申请更多的内存容量,我们先看看下面这样的代码大概用了多少内存:
$a = [
'11111111111111111111111111111111111111',
'11111111111111111111111111111111111111',
'11111111111111111111111111111111111111',
'11111111111111111111111111111111111111',
'11111111111111111111111111111111111111',
'11111111111111111111111111111111111111',
'11111111111111111111111111111111111111',
];
echo memory_get_peak_usage(); //这个函数可以获取内存峰值
我这里运行结果是输出了120216
,表示直到调用memory_get_peak_usage函数的时候为止,操作系统一共为PHP进程分配了120216B内存,大概就是117KB
你的运行结果和我的不一定是一样的,看我们的环境具体情况,但误差不会很大,总不会是我得出117KB,而你你就得出2MB这样嘛
unset销毁变量后,内存峰值并不会下降 ¶
有些小有经验的程序员都觉得:我积极地去unset变量应该就能节省内存提高性能了
但你可能想错了,看看这个代码实验:
echo memory_get_peak_usage() . PHP_EOL; //120984
$b = [
new stdClass(),
new stdClass(),
new stdClass(),
get_declared_classes(),
get_declared_classes(),
get_declared_classes(),
get_declared_classes(),
get_declared_classes(),
get_declared_classes(),
get_defined_vars(),
get_defined_vars(),
get_defined_vars(),
get_defined_vars(),
get_defined_vars(),
get_defined_vars(),
get_defined_vars(),
get_defined_vars(),
get_defined_vars(),
get_defined_vars(),
];
echo memory_get_peak_usage() . PHP_EOL; //215576 新增个大数组后的峰值
unset($b);
echo memory_get_peak_usage(); //215600 都unset了变量,为什么峰值还是这么高?
对,为什么unset了还是那么高?继续往下
内存循环利用 ¶
unset一个变量后,PHP会将这个变量腾出的空间存到自己的“私房钱”里而不是交还给系统,此时系统一直认为“这个PHP进程就是用了很多内存”
如果再有新变量什么的,PHP就先看看“私房钱”能顶用多少,顶多少算多少,不够用再向系统申请新的内存
$a = [
$_SERVER
];
echo memory_get_peak_usage() . PHP_EOL; //132320
$b = [
new stdClass(),
new stdClass(),
new stdClass(),
get_declared_classes(),
get_defined_vars(),
];
echo memory_get_peak_usage() . PHP_EOL; //147048
//接下来如果新增$c会导致增加对吧!?
unset($a, $b);
echo memory_get_peak_usage() . PHP_EOL; //147048 销毁了峰值也不会下降
$c = [
[
$_SERVER,
]
];
echo memory_get_peak_usage(); //147072
以上执行unset($a, $b)
后再申请$c变量,内存峰值从147048增长到147072,共增长24B,但我可以保证$c变量里面的$_SERVER变量值内容不止24B
接下来尝试将unset语句注释掉,我看到的是从147000增长到147408,共增长408B
这里意味着什么?就是说当销毁a b两个变量后,腾出的空间用在c身上了,所以新增c时所扩展的内存空间仅只有24B
如果不执行unset的话,那就没私房钱可以花了