Keep Your Memory
Under Control
Konstantin Kovshenin
konstantin.blog
Fast
Fast
Expensive
Fast
Expensive
Never enough
Memory Usage
free
top, htop, ...
free
free
top
top
PHP / WordPress
Zend Memory Manager
Zend Memory Manager
OS Kernel
foo.php
$a = 5;
malloc, mmap, ...
memory_get_usage()
memory_get_peak_usage()
Debug Bar, Query Monitor
Memory Usage
$before = memory_get_usage();
// Do something
$after = memory_get_usage();
echo $after - $before;
Environment loaded
Init action
Shutdown action
12.9 MB
14.1 MB
14.4 MB
12.9 MB
14.1 MB
14.4 MB
12.9 MB
27.3 MB
28.6 MB
Environment loaded
Init action
Shutdown action
Fatal error: Allowed memory size
of 134217728 bytes exhausted
... tried to allocate 8552 bytes in
/path/to/wp-includes/wp-db.php
on line 1775
... tried to allocate 8552 bytes in
/path/to/wp-includes/wp-db.php
on line 1775
1775: while ( $row = mysqli_fetch_object( ...
... tried to allocate 8552 bytes in
/path/to/wp-includes/wp-db.php
on line 1775
1775: while ( $row = mysqli_fetch_object( ...
Google...
ini_set( 'memory_limit', '2048M' );
Stop
ini_set( 'memory_limit', '2048M' );


script.php
script.php


Zend
Memory
Manager
script.php
2GB
2GB
script.php


Zend
Memory
Manager
Kernel
script.php
2GB
2GB
2x2GB
script.php
OOM Killer
OOM Killer
mysqld
nginx
sshd
postfix
fail2ban
1. Fine-tune the OOM
1. Fine-tune the OOM
2. Add more Swap memory
1. Fine-tune the OOM
2. Add more Swap memory
3. Figure things out
... tried to allocate 8552 bytes in
/path/to/wp-includes/wp-db.php
on line 1775
xdebug
xhprof, tideways
memprof
Memory Profiling
Call Stack:
34032184 6. do_action()
.../htdocs/wp-settings.php:393
34925000 7. call_user_func_array:{}()
.../wp-includes/plugin.php:525
34925104 8. my_plugin_init()
.../wp-includes/plugin.php:525
134139664 9. wpdb->query()
.../wp-content/plugins/memory.php:25
134172496 10. mysqli_fetch_object()
.../wp-includes/wp-db.php:1775
XDEBUG_TRACE
tracefile-analyser.php
Memory Profiling
vim trace.xt
Why?
posts_per_page => -1
// Pretty bad
$posts = get_posts( array(
'posts_per_page' => -1,
// ...
) );
foreach ( $posts as $post ) {
// ...
}
// A little better
$paged = 1;
while ( $posts = get_posts( array(
'posts_per_page' => 100,
'paged' => $paged++,
) ) ) {
foreach ( $posts as $post ) {
// ...
}
}
// Good
wp_suspend_cache_addition( true );
$paged = 1;
while ( $posts = get_posts( array(
'posts_per_page' => 100,
'paged' => $paged++,
) ) ) {
// foreach ...
}
wp_suspend_cache_addition( false );
file_get_contents()
readfile()
fopen/fread/feof
X-Accel-Redirect
ob_start()
// Not so good
ob_start( 'ob_callback' );
// Much better
ob_start( 'ob_callback', 1024*1024*2 );
function ob_callback( $content, $phase ) {
// ...
}
Context
is_admin()
is_network_admin()
is_front_page()
is_singular()
...
template_redirect
wp_head
wp_footer
shutdown
cron
Context
Monitoring
top, free
cat /proc/meminfo
cat /proc/pid/{status,maps}
add_action( 'shutdown', function() {
$line = json_encode( array(
'timestamp' => time(),
'request_uri' => $_SERVER['REQUEST_URI'],
'peak_memory' => memory_get_peak_usage(),
) );
file_put_contents( '/tmp/php-memory.log',
$line . PHP_EOL, FILE_APPEND | LOCK_EX );
});
Kibana
Elasticsearch
Logstash
php-memory.log
Munin
1. Choose the right context
2. Profile with large datasets
3. Keep consumption
under control
konstantin.blog/wcsof2016
Attributions:
Success Kid (Sammy Griner): https://en.wikipedia.org/wiki/Success_Kid
Ninja character: http://www.vecteezy.com/vector-art/88129-ninja-vector-set
Blood spatter CC-Attr-ShareALike 4.0: http://www.freevector.com/splattered-blood-graphics-set
User icons by FontAwesome, SIL OFL 1.1: http://fontawesome.io
Memory Management in WordPress

Memory Management in WordPress