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 の関数は常にグローバルです。つまり、スクリプトの最後まで存在します。そのため、呼び出すたびにメモリが割り当てられ、割り当てが解除されることはありません。

関数は 1 回だけ作成する必要があります。または、メモリ リークを取り除くために、コールバックを使用してすべてを書き直すことができると確信しています。

于 2012-04-28T11:57:22.297 に答える