2

我在 PHP 中有一个长时间运行的操作,它总是因内存不足而崩溃。

所以我开始记录内存使用情况:

        $result = memory_get_usage() / 1024;
        echo $result;

通过注释部分代码,我找到了“有罪”的代码,负责吃掉我所有的 ram。

这是代码:

        static private function from_camel_case($str)
        {
            $str[0] = strtolower($str[0]);
            $func = create_function('$c', 'return "_" . strtolower($c[1]);');
            $result = preg_replace_callback('/([A-Z])/', $func, $str);
            return $result;
        }

它基本上将驼峰式的文本转换为带下划线的小写。

为什么会这样泄漏?

我在 Mac OS X Lion 上的 MAMP 中运行 PHP 5.3.5

4

3 回答 3

4

因为每次该函数运行时您都在创建一个新函数。

由于您使用的是 5.3,因此您可以create_function用匿名函数替换,看看是否有帮助:

    static private function from_camel_case($str)
    {
        $str[0] = strtolower($str[0]);
        $result = preg_replace_callback('/([A-Z])/', function($matches) {
          return '_' . strtolower($matches[1]);
        }, $str);
        return $result;
    }

或者将回调提取到普通函数中:

    static private function from_camel_case($str)
    {
        $str[0] = strtolower($str[0]);
        $result = preg_replace_callback('/([A-Z])/', array(__CLASS__, 'replace_case'), $str);
        return $result;
    }

    static private function replace_case($matches) {
      return '_' . strtolower($matches[1]);
    }
于 2012-04-28T12:02:03.963 回答
3

如果您一遍又一遍地调用该代码,问题就出在这一行:

$func = create_function('$c', 'return "_" . strtolower($c[1]);');

每次调用该代码时,它都会创建一个新的匿名函数。根据http://www.php.net/create_function将代码放入全局命名空间,因此方法完成时不会删除该函数。

于 2012-04-28T11:56:50.177 回答
3

create_function您每次调用它时都会使用它来创建一个函数。PHP 中的函数始终是全局的,这意味着它会一直存在到脚本结束。这就是为什么每次调用它时,它都会分配一些内存并且永远不会释放它。

你应该只创建一次函数,或者我相信你可以使用回调重写整个事情来摆脱内存泄漏。

于 2012-04-28T11:57:22.297 回答