memory managment php (english)

22
Memory Management IN PHP Writen by: Mahmoud Masih Tehrani Email:[email protected]

Upload: mahmood-masih-tehrani

Post on 16-Jul-2015

104 views

Category:

Education


3 download

TRANSCRIPT

Page 1: Memory managment php (english)

Memory Management IN PHP

Writen by: Mahmoud Masih TehraniEmail:[email protected]

Page 2: Memory managment php (english)

The golden rule

The number one thing to do when you encounter (or expect to encounter) memory pressure is: do not read massive amounts of data in memory at once if you intend to process them sequentially.

Page 3: Memory managment php (english)

Examples

Do not fetch a large result set in memory as an array; instead, fetch each row in turn and process it before fetching the next

Do not read large text files in memory (e.g. with file); instead, read one line at a time

Following this practice religiously will "automatically" take care of other things for you as well:

There is no longer any need to clean up resources with a big memory footprint by closing them and losing all references to them on purpose, because there will be no such resources to begin with

There is no longer a need to unset large variables after you are done with them, because there will be no such variables as well

Page 4: Memory managment php (english)

Other things to do

Be careful of creating closures inside loops; this should be easy to do, as creating such inside loops is a bad code smell. You can always lift the closure upwards and give it more parameters.

When expecting massive input, design your program and pick algorithms accordingly. For example, you can mergesort any amount of text files of any size using a constant amount of memory.

Page 5: Memory managment php (english)

Another suggest

When you compute your large array of objects, try to not compute it all at once. Walk in steps and process elements as you walk then free memory and take next elements.

It will take more time, but you can manage the amount of memory you use.

Page 6: Memory managment php (english)

And Another suggest

You could try profiling it puting some calls to memory_get_usage(), to look for the place where it's peaking.

Of course, knowing what the code really does you'll have more information to reduce its memory usage.

Page 7: Memory managment php (english)

memory_get_usage

(PHP 4 >= 4.3.2, PHP 5)

memory_get_usage — Returns the amount of memory allocated to PHP

int memory_get_usage ([ bool $real_usage = false ] )

Returns the amount of memory, in bytes, that's currently being allocated to your PHP script.

Returns the memory amount in bytes.

Page 8: Memory managment php (english)

Example #1 A memory_get_usage() example

<?php

// This is only an example, the numbers below will

// differ depending on your system

echo memory_get_usage() . "\n"; // 36640

$a = str_repeat("Hello", 4242);

echo memory_get_usage() . "\n"; // 57960

unset($a);

echo memory_get_usage() . "\n"; // 36744

?>

Page 9: Memory managment php (english)

memory_limit integer

This sets the maximum amount of memory in bytes that a script is allowed to allocate. This helps prevent poorly written scripts for eating up all available memory on a server. Note that to have no memory limit, set this directive to -1.

Prior to PHP 5.2.1, in order to use this directive it had to be enabled at compile time by using --enable-memory-limit in the configure line. This compile-time flag was also required to define the functions memory_get_usage() and memory_get_peak_usage() prior to 5.2.1.

When an integer is used, the value is measured in bytes. Shorthand notation, as described in this FAQ, may also be used.

See also: max_execution_time.

Page 10: Memory managment php (english)

Memory Management

In C, you always have to worry about memory management. This still holds true when writing PHP extensions in C, but the extension API provides you with a safety net and some helpful debugging facilities if you use the API's memory-management wrapper functions (you are strongly encouraged to do so).

Page 11: Memory managment php (english)

The most important of its features for the Hacker, and the first thing to mention is tracking allocations. Tracking allocations allow the memory manager to avoid leaks, a thorn in the side of most Hackers. When PHP is built in debug mode (--enable-debug), detected leaks are reported, in a perfect world they would never get to deployment.

Page 12: Memory managment php (english)

The wrapper functions are

● emalloc( )● efree( )● estrdup( )● estrndup( )● ecalloc( )● erealloc( )

Page 13: Memory managment php (english)

One of the features you get by using emalloc( ) is a safety net for memory leaks. If you emalloc( ) something and forget to efree( ) it, PHP prints a leak warning like this if you are running in debug mode (enabled by compiling PHP with the --enable-debug switch):

foo.c(123) : Freeing 0x0821E5FC (20 bytes), script=foo.php

Last leak repeated 1 time

Page 14: Memory managment php (english)

If you efree( ) something that was allocated using malloc( ) or some mechanism other than the PHP memory-management functions, you get the following:

---------------------------------------

foo.c(124) : Block 0x08219C94 status:

Beginning: Overrun (magic=0x00000000, expected=0x7312F8DC)

End: Unknown

---------------------------------------

foo.c(124) : Block 0x0821EB1C status:

Beginning: Overrun (magic=0x00000000, expected=0x7312F8DC)

End: Unknown

---------------------------------------

Page 15: Memory managment php (english)

In this case, line 124 in foo.c is the call to efree( ). PHP knows it didn't allocate this memory because it didn't contain the magic token that indicates a PHP allocation.

The emalloc( )/efree( ) safety net also catches overruns—e.g., if you emalloc(20) but write 21 bytes to that address. For example:

123: s = emalloc(6);

124: strcpy(s,"Rasmus");

125: efree(s);

Page 16: Memory managment php (english)

Because this code failed to allocate enough memory to hold the string and the terminating NULL, PHP prints this warning:

---------------------------------------

foo.c(125) : Block 0x08219CB8 status:

Beginning: OK (allocated on foo.c:123, 6 bytes)

End: Overflown (magic=0x2A8FCC00 instead of 0x2A8FCC84)

1 byte(s) overflown

---------------------------------------

foo.c(125) : Block 0x08219C40 status:

Beginning: OK (allocated on foo.c:123, 6 bytes)

End: Overflown (magic=0x2A8FCC00 instead of 0x2A8FCC84)

1 byte(s) overflown

---------------------------------------

Page 17: Memory managment php (english)

The warning shows where the overflowed memory was allocated (line 123) and where this overflow was detected (line 125 in the efree( ) call).

Page 18: Memory managment php (english)

These memory-handling functions can catch a lot of silly little mistakes that might otherwise waste your time, so do your development with the debug switch enabled. Don't forget to recompile in non-debug mode when you are done testing, though, as the various tests done by the emalloc( ) type functions slow down PHP.

Page 19: Memory managment php (english)

An extension compiled in debug mode does not work in an instance of PHP not compiled in debug mode. When PHP loads an extension, it checks to see if the debug setting, the thread-safety setting, and the API version all match. If something doesn't match, you will get a warning like this:

Warning: foo: Unable to initialize module

Module compiled with debug=0, thread-safety=0 module API=20010901

PHP compiled with debug=1, thread-safety=0 module API=20010901

Page 20: Memory managment php (english)

If you compile the Apache module version of PHP with the --enable-memory-limit switch, it will add the script's peak memory usage to the Apache r->notes table. You can access this information from other Apache modules, such as mod_log_config. Add this string to your Apache LogFormat line to log the peak number of bytes a script used:

%{mod_php_memory_usage}n

Page 21: Memory managment php (english)

If you're having problems with a module allocating too much memory and grinding your system into the ground, build PHP with the memory-limit option enabled. This makes PHP heed the memory_limit directive in your php.ini file, terminating a script if it tries to allocate more memory than the specified limit. This results in errors like this:

Fatal error: Allowed memory size of 102400 bytes exhausted at ...

(tried to allocate 46080 bytes) in /path/script.php on line 35

Page 22: Memory managment php (english)

refrence

● http://php.net/manual/en/internals2.memory.php

● http://docstore.mik.ua/orelly/webprog/php/ch14_05.htm

● http://stackoverflow.com/questions/7517389/best-practices-for-managing-memory-in-a-php-script