我有一个用PHP编写的脚本,它使用AWS Dynamo PHP API。它运行一个很长的循环,从发电机中提取大量数据,然后处理它。
当我使用'top'观察进程时,我可以看到'php'进程使用的内存使用情况
在我的脚本循环中,我打印memory_get_usage(true)的结果
当我运行我的测试时,这两个值甚至都不相似......
他们应该吗?如果不是为什么不呢?
在我的测试中,我有一个1.7gb ram的服务器,我已经将php.ini的memory_limit设置为64M。我也在脚本的开头调用gc_enable(),并在每个循环之间调用gc_collect_cycles(),以期强制进行垃圾回收。
当我使用'top'观看我的php脚本时,我可以看到%MEM上升,直到它最终超过95%并且linux杀死了php进程,我从查看'dmesg'就知道了。当我查看循环的每次迭代中的打印输出时,memory_get_usage(true)报告的内存使用量永远不会超过50mb。
Linux认为该脚本使用了近1.7GB,php认为它只使用50mb!
会发生什么事?
即使脚本有内存泄漏,我也不明白为什么memory_get_usage(true)没有占用内存......
花了一些时间评论我在循环中运行的处理的各个部分后,我发现如果我删除以下代码:
class cMyClass {
public static function static_cmp_fn(&$a, &$b) {
if ($a['att'] == $b['att']) { return 0; }
$ret = ($a['att'] < $b['att']) ? -1 : +1;
return $ret;
}
function DoProcessing(){
$sort_fn = array("cMyClass", "static_cmp_fn");
usort($this->m_dictToSort, $sort_fn);
unset($sort_fn);
}
}
php从不吃掉所有的系统内存。在我看来,usort是泄漏记忆,我不知道为什么。我不明白的是为什么PHP会报告有关它使用多少内存的错误信息......
有什么想法吗?
答案 0 :(得分:1)
花了一些时间评论我在循环中运行的处理的各个部分后,我发现如果我删除以下代码:
$sort_fn = array("cMyClass", "static_cmp_fn");
usort($this->m_dictToSort, $sort_fn);
php从不吃掉所有的系统内存。在我看来,这是因为泄漏记忆,我不知道为什么。
显然是。参见手册:
http://php.net/manual/en/function.usort.php
“这里有几个例子提倡使用'create_function'进行排序,由于usort的限制,这很容易使用。但要注意这个方法 - 创建的函数不会在结束时释放排序例程,这会产生内存泄漏。因此,应该永远不要使用此方法。“
array()
方法似乎做了类似的事情。你可以声明一个外部调用你的方法的包装函数吗?
<强>更新强>
尝试构建一个小测试用例,看看会发生什么。到目前为止,我无法重现泄漏;可能包含有关static_cmp_fn()
执行操作以及m_dictToSort
结构的更多数据。简单的比较不会引发任何奇怪的事情。也不在循环中分配字符串,数组或对象。垃圾收集器将其关闭并且内存保持不变。
我通过调用另一个函数来进一步限制问题,该函数根本不排序,或做一个非常基本的排序,以查看问题是否在usort
做某事有趣的是它可以调用,正如我想的那样(似乎没有,我错了)或者比较函数中是否发生了一些有趣的事情。