2

I have a long running operation in PHP and it always crashed with an out of memory.

So i started logging mem usage with:

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

By commenting parts of the code I found the "guilty" one, responsible for eating up all my ram.

This is the code:

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

It basically converts text in camelcase to lowercase with underscores.

Why is this leaking?

I am running PHP 5.3.5 in MAMP on my Mac OS X Lion

2
  • You can use preg_replace to prefix upper cased letter with _ and then apply strtolower to the whole string. It will prevent of using callbacks and creating functions Commented Apr 28, 2012 at 11:57
  • It is not leaking memory, you just don't know where the memory is being used. See the answers. Commented Apr 28, 2012 at 12:00

3 Answers 3

4

Because you're creating a new function every time that function runs.

Since you're using 5.3, you can replace create_function with an anonymous function and see if that helps:

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

Or extract the callback into a normal function:

    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]);
    }
Sign up to request clarification or add additional context in comments.

1 Comment

You forgot to remove the old create_function call.
3

You are creating a function using create_function every time you call it. Functions in PHP are always global, which means it will exist till the end of the script. That's why every time you call it, it will allocate some memory and never deallocate it.

You should create the function only once, or I's sure you can rewrite the whole thing using callbacks to get rid of the memory leak.

1 Comment

Indeed! That is the problem. Thanks! Still have to wait 8 minutes before I can accept this answer though :(
3

If you're calling that code over and over again the problem is this line:

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

That code creates a new anonymous function every time you call it. According to http://www.php.net/create_function the code is put into the global namespace, so the function is not removed when the method is completed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.