php memory_get_usage(true)vs top%MEM

sun*_*ant 7 php memory memory-leaks memory-management

我有一个用PHP编写的脚本,它使用AWS Dynamo PHP API.它运行一个很长的循环,从发电机中提取大量数据,然后处理它.

当我使用'top'观察进程时,我可以看到'php'进程使用的内存使用情况

在我的脚本循环中,我打印memory_get_usage的结果(true)

当我运行我的测试时,这两个值甚至都不相似......

他们应该吗?如果不是为什么不呢?

在我的测试中,我有一个1.7gb内存的服务器,我已经将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)不占内存...

UPDATE

花了一些时间评论我在循环中运行的处理的各个部分,我发现如果我删除以下代码:

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);
    }

}
Run Code Online (Sandbox Code Playgroud)

php从不吃掉所有的系统内存.在我看来,usort是泄漏记忆,我不知道为什么.我不明白的是为什么PHP会报告有关它使用多少内存的错误信息...

有任何想法吗?

LSe*_*rni 1

在花了一些时间注释掉处理的各个部分之后,我在循环中运行,我发现如果删除以下代码:

$sort_fn = array("cMyClass", "static_cmp_fn");
usort($this->m_dictToSort, $sort_fn); 
Run Code Online (Sandbox Code Playgroud)

php 永远不会占用所有系统内存。在我看来,usort 正在泄漏内存,我不知道为什么。

显然是这样。请参阅手册:

http://php.net/manual/en/function.usort.php

“这里有几个例子提倡使用‘create_function’进行排序,由于 usort 的限制,使用这种方法很诱人。但要注意这种方法——创建的函数在排序例程结束时不会被释放,这会创建内存泄漏。因此,可能永远不应该使用此方法。”

array()方法似乎做了类似的事情。您可以声明一个包装函数,它在外部调用您的方法,也许?

更新

尝试构建一个小测试用例来看看会发生什么。到目前为止我还无法重现泄漏;也许有更多关于什么static_cmp_fn()是做什么以及如何m_dictToSort构建的数据。简单的比较不会引发任何奇怪的事情。在循环内分配字符串、数组或对象也不会。垃圾收集器会杀死它们并且内存保持较低水平。

我会通过调用另一个根本不排序的函数或进行非常基本的排序来进一步限制问题,以查看问题是否在于usort用它的可调用函数做一些有趣的事情,正如我所想的那样(看起来它并不,我错了)或者比较函数内部发生了一些有趣的事情。