PHP函数内存占用测量问题:循环迭代后内存数值异常如何解决?
问题原因与解决方法
为什么第一次内存占用更高?
第一次调用getBasketsExceedTotal时,PHP会完成一系列一次性初始化操作:加载相关类的定义、解析函数字节码、初始化内部缓存等,这些额外开销会被算入首次执行的内存消耗里。后续调用时,这些资源已经加载完成,内存占用就只反映函数实际运行时的内存开销,因此数值远低于第一次。
处理方案
1. 先预热再测试(推荐)
如果要测量函数重复执行时的内存开销,可以在正式循环前先调用一次函数,让PHP完成所有初始化工作,之后的测试结果就都是函数实际运行的内存消耗:
// 预热:提前触发初始化操作 $customer->getBasketsExceedTotal(total: 5); $memoryWithFilter = []; for ($i = 0; $i < 10; $i++) { $memoryStart = memory_get_usage(); $basketsWithFilter = $customer->getBasketsExceedTotal(total: 5); $memoryEnd = memory_get_usage() - $memoryStart; $memoryWithFilter[] = round($memoryEnd / 1024); // 可选:每次迭代后清理变量,避免内存累积影响结果 unset($basketsWithFilter); }
这样得到的结果数组会趋于一致,直接计算平均值即可。
2. 按需选择统计范围
- 若需要统计首次执行的总开销(包含初始化成本),直接使用第一次的17KB数值即可,后续的2KB是重复执行的开销,两者意义不同,无需混在一起计算平均值。
- 若想同时统计两种场景,可以分别记录首次开销和后续平均开销:
$memoryWithFilter = []; for ($i = 0; $i < 10; $i++) { $memoryStart = memory_get_usage(); $basketsWithFilter = $customer->getBasketsExceedTotal(total: 5); $memoryEnd = memory_get_usage() - $memoryStart; $memoryWithFilter[] = round($memoryEnd / 1024); unset($basketsWithFilter); } // 首次执行总开销 $firstRunMemory = $memoryWithFilter[0]; // 后续重复执行的平均开销 $averageRepeatMemory = array_sum(array_slice($memoryWithFilter, 1)) / 9;
3. 内存统计细节优化
memory_get_usage()获取的是脚本当前已使用的内存,每次迭代后用unset()清理生成的变量,能避免变量累积导致的内存偏差。- 如果想获取PHP实际向系统申请的内存(包括预留的内存块),可以用
memory_get_usage(true),但这个数值波动可能更大,按需选择即可。
内容的提问来源于stack exchange,提问作者wollenS
相关产品推荐
相关产品推荐

