SlideShare a Scribd company logo
1 of 60
Download to read offline
Пожиратели памяти
в WordPress
Константин Ковшенин
Быстрая
Быстрая
Дорогая
Быстрая
Дорогая
Всегда мало
Потребление памяти:
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
Потребление памяти:
$before = memory_get_usage();
// Делаем что-нибудь
$after = memory_get_usage();
echo $after - $before;
Загрузка ядра
Событие init
Событие shutdown
12.9 мб
14.1 мб
14.4 мб
Загрузка ядра
Событие init
Событие shutdown
12.9 мб
14.1 мб
14.4 мб
12.9 мб
27.3 мб
28.6 мб
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( ...
Гуглим
ini_set( 'memory_limit', '2048M' );
Стоп
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. Конфигурация OOM
1. Конфигурация OOM
2. Добавить много swap-памяти
1. Конфигурация OOM
2. Добавить много swap-памяти
3. Разобраться
... tried to allocate 8552 bytes in
/path/to/wp-includes/wp-db.php
on line 1775
xdebug
xhprof
memprof
Профилирование памяти:
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
Профилирование памяти:
vim trace.xt
Ошибки
posts_per_page => -1
// Плохо
$posts = get_posts( array(
'posts_per_page' => -1,
// ...
) );
foreach ( $posts as $post ) {
// ...
}
// Чуть лучше
$paged = 1;
while ( $posts = get_posts( array(
'posts_per_page' => 100,
'paged' => $paged++,
) ) ) {
foreach ( $posts as $post ) {
// ...
}
}
// Хорошо
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()
// Плохо
ob_start( 'ob_callback' );
// Хорошо
ob_start( 'ob_callback', 1024*1024*2 );
function ob_callback( $content, $phase ) {
// ...
}
Контекст
is_admin()
is_network_admin()
is_front_page()
is_singular()
...
template_redirect
wp_head
wp_footer
shutdown
cron
Контекст
Мониторинг
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. Выбирайте контекст
2. Профилируйте с большим
количеством данных
3. Держите потребление
под контролем
kovshenin.com/wcmsk2016
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
Пожиратели памяти в WordPress

More Related Content

What's hot

распределенное файловое хранилище (Nginx, zfs, perl). перепелица мамонтов. зал 2
распределенное файловое хранилище (Nginx, zfs, perl). перепелица мамонтов. зал 2распределенное файловое хранилище (Nginx, zfs, perl). перепелица мамонтов. зал 2
распределенное файловое хранилище (Nginx, zfs, perl). перепелица мамонтов. зал 2rit2011
 
Приёмы разработки высоконагруженных приложений на Twisted (Андрей Смирнов)
Приёмы разработки высоконагруженных приложений на Twisted (Андрей Смирнов)Приёмы разработки высоконагруженных приложений на Twisted (Андрей Смирнов)
Приёмы разработки высоконагруженных приложений на Twisted (Андрей Смирнов)Ontico
 
Android emulators features
Android emulators featuresAndroid emulators features
Android emulators featuresRoman Butok
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptSmartTools
 
Работа с большими файлами под перлом‎
Работа с большими файлами под перлом‎Работа с большими файлами под перлом‎
Работа с большими файлами под перлом‎mayperl
 
PHP 5.4: Что нового?
PHP 5.4: Что нового?PHP 5.4: Что нового?
PHP 5.4: Что нового?phpdevby
 
05 - Web-технологии. Сетевые протоколы
05 - Web-технологии. Сетевые протоколы05 - Web-технологии. Сетевые протоколы
05 - Web-технологии. Сетевые протоколыRoman Brovko
 
"Web Audio Api", Анатолий Найда, MoscowJS 27
"Web Audio Api", Анатолий Найда, MoscowJS 27"Web Audio Api", Анатолий Найда, MoscowJS 27
"Web Audio Api", Анатолий Найда, MoscowJS 27MoscowJS
 
ProcessingとMaxMSPの連携
ProcessingとMaxMSPの連携ProcessingとMaxMSPの連携
ProcessingとMaxMSPの連携Aki Sato
 
2013 09 19 кеширование на клиенте и сервере
2013 09 19 кеширование на клиенте и сервере2013 09 19 кеширование на клиенте и сервере
2013 09 19 кеширование на клиенте и сервереYandex
 
Present saint-per3-by-pavel-vlasov
Present saint-per3-by-pavel-vlasovPresent saint-per3-by-pavel-vlasov
Present saint-per3-by-pavel-vlasovPavel Vlasov
 
простой и мощный бэкап на базе rsync
простой и мощный бэкап на базе rsyncпростой и мощный бэкап на базе rsync
простой и мощный бэкап на базе rsyncAndrew Pantyukhin
 
Drupal 8 API для разработчиков
Drupal 8 API для разработчиковDrupal 8 API для разработчиков
Drupal 8 API для разработчиковDrupalSPB
 
Perl для не программистов. Николай Мишин. Moscow.pm 4 июля 2013
Perl для не программистов. Николай Мишин. Moscow.pm 4 июля 2013Perl для не программистов. Николай Мишин. Moscow.pm 4 июля 2013
Perl для не программистов. Николай Мишин. Moscow.pm 4 июля 2013Moscow.pm
 
Пластилиновый код: как перестать кодить и начать жить
Пластилиновый код: как перестать кодить и начать житьПластилиновый код: как перестать кодить и начать жить
Пластилиновый код: как перестать кодить и начать житьMoscow.pm
 
Нейронные сети на JS
Нейронные сети на JSНейронные сети на JS
Нейронные сети на JSVsevolod Rodionov
 

What's hot (19)

Парсер: что? зачем? как?
Парсер: что? зачем? как?Парсер: что? зачем? как?
Парсер: что? зачем? как?
 
распределенное файловое хранилище (Nginx, zfs, perl). перепелица мамонтов. зал 2
распределенное файловое хранилище (Nginx, zfs, perl). перепелица мамонтов. зал 2распределенное файловое хранилище (Nginx, zfs, perl). перепелица мамонтов. зал 2
распределенное файловое хранилище (Nginx, zfs, perl). перепелица мамонтов. зал 2
 
Приёмы разработки высоконагруженных приложений на Twisted (Андрей Смирнов)
Приёмы разработки высоконагруженных приложений на Twisted (Андрей Смирнов)Приёмы разработки высоконагруженных приложений на Twisted (Андрей Смирнов)
Приёмы разработки высоконагруженных приложений на Twisted (Андрей Смирнов)
 
Android emulators features
Android emulators featuresAndroid emulators features
Android emulators features
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
 
Почему Mojolicious?
Почему Mojolicious?Почему Mojolicious?
Почему Mojolicious?
 
Работа с большими файлами под перлом‎
Работа с большими файлами под перлом‎Работа с большими файлами под перлом‎
Работа с большими файлами под перлом‎
 
PHP 5.4: Что нового?
PHP 5.4: Что нового?PHP 5.4: Что нового?
PHP 5.4: Что нового?
 
05 - Web-технологии. Сетевые протоколы
05 - Web-технологии. Сетевые протоколы05 - Web-технологии. Сетевые протоколы
05 - Web-технологии. Сетевые протоколы
 
"Web Audio Api", Анатолий Найда, MoscowJS 27
"Web Audio Api", Анатолий Найда, MoscowJS 27"Web Audio Api", Анатолий Найда, MoscowJS 27
"Web Audio Api", Анатолий Найда, MoscowJS 27
 
ProcessingとMaxMSPの連携
ProcessingとMaxMSPの連携ProcessingとMaxMSPの連携
ProcessingとMaxMSPの連携
 
2013 09 19 кеширование на клиенте и сервере
2013 09 19 кеширование на клиенте и сервере2013 09 19 кеширование на клиенте и сервере
2013 09 19 кеширование на клиенте и сервере
 
Wordpress Cron
Wordpress CronWordpress Cron
Wordpress Cron
 
Present saint-per3-by-pavel-vlasov
Present saint-per3-by-pavel-vlasovPresent saint-per3-by-pavel-vlasov
Present saint-per3-by-pavel-vlasov
 
простой и мощный бэкап на базе rsync
простой и мощный бэкап на базе rsyncпростой и мощный бэкап на базе rsync
простой и мощный бэкап на базе rsync
 
Drupal 8 API для разработчиков
Drupal 8 API для разработчиковDrupal 8 API для разработчиков
Drupal 8 API для разработчиков
 
Perl для не программистов. Николай Мишин. Moscow.pm 4 июля 2013
Perl для не программистов. Николай Мишин. Moscow.pm 4 июля 2013Perl для не программистов. Николай Мишин. Moscow.pm 4 июля 2013
Perl для не программистов. Николай Мишин. Moscow.pm 4 июля 2013
 
Пластилиновый код: как перестать кодить и начать жить
Пластилиновый код: как перестать кодить и начать житьПластилиновый код: как перестать кодить и начать жить
Пластилиновый код: как перестать кодить и начать жить
 
Нейронные сети на JS
Нейронные сети на JSНейронные сети на JS
Нейронные сети на JS
 

Viewers also liked

Основые безопасности WordPress
Основые безопасности WordPressОсновые безопасности WordPress
Основые безопасности WordPressKonstantin Kovshenin
 
Почему HTTPS соединение необходимо реализовать на Вашем сайте?
Почему HTTPS соединение необходимо реализовать на Вашем сайте?Почему HTTPS соединение необходимо реализовать на Вашем сайте?
Почему HTTPS соединение необходимо реализовать на Вашем сайте?Alexey Vidanov
 
Цикл разработки WordPress
Цикл разработки WordPressЦикл разработки WordPress
Цикл разработки WordPressKonstantin Kovshenin
 
7 убийц производительности WordPress
7 убийц производительности WordPress7 убийц производительности WordPress
7 убийц производительности WordPressKonstantin Kovshenin
 
WordPress под нагрузкой: масштабирование и отказоустойчивость
WordPress под нагрузкой: масштабирование и отказоустойчивостьWordPress под нагрузкой: масштабирование и отказоустойчивость
WordPress под нагрузкой: масштабирование и отказоустойчивостьKonstantin Kovshenin
 

Viewers also liked (9)

Секреты WP_Query
Секреты WP_QueryСекреты WP_Query
Секреты WP_Query
 
P2
P2P2
P2
 
Основые безопасности WordPress
Основые безопасности WordPressОсновые безопасности WordPress
Основые безопасности WordPress
 
Почему HTTPS соединение необходимо реализовать на Вашем сайте?
Почему HTTPS соединение необходимо реализовать на Вашем сайте?Почему HTTPS соединение необходимо реализовать на Вашем сайте?
Почему HTTPS соединение необходимо реализовать на Вашем сайте?
 
Цикл разработки WordPress
Цикл разработки WordPressЦикл разработки WordPress
Цикл разработки WordPress
 
The Settings API
The Settings APIThe Settings API
The Settings API
 
7 убийц производительности WordPress
7 убийц производительности WordPress7 убийц производительности WordPress
7 убийц производительности WordPress
 
Memory Management in WordPress
Memory Management in WordPressMemory Management in WordPress
Memory Management in WordPress
 
WordPress под нагрузкой: масштабирование и отказоустойчивость
WordPress под нагрузкой: масштабирование и отказоустойчивостьWordPress под нагрузкой: масштабирование и отказоустойчивость
WordPress под нагрузкой: масштабирование и отказоустойчивость
 

Similar to Пожиратели памяти в WordPress

Практичне профілювання продуктивності
Практичне профілювання продуктивностіПрактичне профілювання продуктивності
Практичне профілювання продуктивностіShtrih Sruleg
 
Глеб Грицай - Forensics
Глеб Грицай - ForensicsГлеб Грицай - Forensics
Глеб Грицай - ForensicsPositive Hack Days
 
Low-level C/C++ Optimization by Anrew Axenov (Sphinx)
Low-level C/C++ Optimization by Anrew Axenov (Sphinx)Low-level C/C++ Optimization by Anrew Axenov (Sphinx)
Low-level C/C++ Optimization by Anrew Axenov (Sphinx)Vadim Kosov
 
Низкоуровневая Оптимизация (Андрей Аксенов)
Низкоуровневая Оптимизация (Андрей Аксенов)Низкоуровневая Оптимизация (Андрей Аксенов)
Низкоуровневая Оптимизация (Андрей Аксенов)Ontico
 
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...Ontico
 
Движение по хрупкому дну / Сергей Караткевич (servers.ru)
Движение по хрупкому дну / Сергей Караткевич (servers.ru)Движение по хрупкому дну / Сергей Караткевич (servers.ru)
Движение по хрупкому дну / Сергей Караткевич (servers.ru)Ontico
 
Управление большим количеством физических серверов, Александр Берсенев, Инст...
 Управление большим количеством физических серверов, Александр Берсенев, Инст... Управление большим количеством физических серверов, Александр Берсенев, Инст...
Управление большим количеством физических серверов, Александр Берсенев, Инст...it-people
 
Smirnov Memcached High Load 2008
Smirnov Memcached High Load 2008Smirnov Memcached High Load 2008
Smirnov Memcached High Load 2008Ontico
 
Smirnov Memcached Highload 2008
Smirnov Memcached Highload 2008Smirnov Memcached Highload 2008
Smirnov Memcached Highload 2008Ontico
 
Caching data outside Java Heap and using Shared Memory in Java
Caching data outside Java Heap and using Shared Memory in JavaCaching data outside Java Heap and using Shared Memory in Java
Caching data outside Java Heap and using Shared Memory in JavaAndrei Pangin
 
О безопасном использовании PHP wrappers
О безопасном использовании PHP wrappersО безопасном использовании PHP wrappers
О безопасном использовании PHP wrappersPositive Hack Days
 
Пакетирование для Debian/Ubuntu
Пакетирование для Debian/UbuntuПакетирование для Debian/Ubuntu
Пакетирование для Debian/Ubuntusamsolutionsby
 
Погружение в виртуальную память и большие страницы / Константин Новаковский (...
Погружение в виртуальную память и большие страницы / Константин Новаковский (...Погружение в виртуальную память и большие страницы / Константин Новаковский (...
Погружение в виртуальную память и большие страницы / Константин Новаковский (...Ontico
 
Поговорим про память
Поговорим про памятьПоговорим про память
Поговорим про памятьAndrey Akinshin
 
Видеохостинг своими руками
Видеохостинг своими рукамиВидеохостинг своими руками
Видеохостинг своими рукамиStanislavMalkin
 
Вячеслав Бирюков - Как Linux работает с памятью
Вячеслав Бирюков - Как Linux работает с памятьюВячеслав Бирюков - Как Linux работает с памятью
Вячеслав Бирюков - Как Linux работает с памятьюYandex
 
VDS: обнаружение, выявление причин и устранение проблемных ситуаций. Диагнос...
VDS: обнаружение, выявление причин и устранение проблемных ситуаций.  Диагнос...VDS: обнаружение, выявление причин и устранение проблемных ситуаций.  Диагнос...
VDS: обнаружение, выявление причин и устранение проблемных ситуаций. Диагнос...Oleg Lipin
 

Similar to Пожиратели памяти в WordPress (20)

Практичне профілювання продуктивності
Практичне профілювання продуктивностіПрактичне профілювання продуктивності
Практичне профілювання продуктивності
 
Глеб Грицай - Forensics
Глеб Грицай - ForensicsГлеб Грицай - Forensics
Глеб Грицай - Forensics
 
Low-level C/C++ Optimization by Anrew Axenov (Sphinx)
Low-level C/C++ Optimization by Anrew Axenov (Sphinx)Low-level C/C++ Optimization by Anrew Axenov (Sphinx)
Low-level C/C++ Optimization by Anrew Axenov (Sphinx)
 
Низкоуровневая Оптимизация (Андрей Аксенов)
Низкоуровневая Оптимизация (Андрей Аксенов)Низкоуровневая Оптимизация (Андрей Аксенов)
Низкоуровневая Оптимизация (Андрей Аксенов)
 
Cpp
CppCpp
Cpp
 
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...
 
Движение по хрупкому дну / Сергей Караткевич (servers.ru)
Движение по хрупкому дну / Сергей Караткевич (servers.ru)Движение по хрупкому дну / Сергей Караткевич (servers.ru)
Движение по хрупкому дну / Сергей Караткевич (servers.ru)
 
Управление большим количеством физических серверов, Александр Берсенев, Инст...
 Управление большим количеством физических серверов, Александр Берсенев, Инст... Управление большим количеством физических серверов, Александр Берсенев, Инст...
Управление большим количеством физических серверов, Александр Берсенев, Инст...
 
Smirnov Memcached High Load 2008
Smirnov Memcached High Load 2008Smirnov Memcached High Load 2008
Smirnov Memcached High Load 2008
 
Smirnov Memcached Highload 2008
Smirnov Memcached Highload 2008Smirnov Memcached Highload 2008
Smirnov Memcached Highload 2008
 
php frameworks
php frameworksphp frameworks
php frameworks
 
Caching data outside Java Heap and using Shared Memory in Java
Caching data outside Java Heap and using Shared Memory in JavaCaching data outside Java Heap and using Shared Memory in Java
Caching data outside Java Heap and using Shared Memory in Java
 
бегун
бегунбегун
бегун
 
О безопасном использовании PHP wrappers
О безопасном использовании PHP wrappersО безопасном использовании PHP wrappers
О безопасном использовании PHP wrappers
 
Пакетирование для Debian/Ubuntu
Пакетирование для Debian/UbuntuПакетирование для Debian/Ubuntu
Пакетирование для Debian/Ubuntu
 
Погружение в виртуальную память и большие страницы / Константин Новаковский (...
Погружение в виртуальную память и большие страницы / Константин Новаковский (...Погружение в виртуальную память и большие страницы / Константин Новаковский (...
Погружение в виртуальную память и большие страницы / Константин Новаковский (...
 
Поговорим про память
Поговорим про памятьПоговорим про память
Поговорим про память
 
Видеохостинг своими руками
Видеохостинг своими рукамиВидеохостинг своими руками
Видеохостинг своими руками
 
Вячеслав Бирюков - Как Linux работает с памятью
Вячеслав Бирюков - Как Linux работает с памятьюВячеслав Бирюков - Как Linux работает с памятью
Вячеслав Бирюков - Как Linux работает с памятью
 
VDS: обнаружение, выявление причин и устранение проблемных ситуаций. Диагнос...
VDS: обнаружение, выявление причин и устранение проблемных ситуаций.  Диагнос...VDS: обнаружение, выявление причин и устранение проблемных ситуаций.  Диагнос...
VDS: обнаружение, выявление причин и устранение проблемных ситуаций. Диагнос...
 

More from Konstantin Kovshenin

Будущее WordPress (SPB, 2014)
Будущее WordPress (SPB, 2014)Будущее WordPress (SPB, 2014)
Будущее WordPress (SPB, 2014)Konstantin Kovshenin
 
Road to Platform @ WordPress.com VIP Workshop 2014
Road to Platform @ WordPress.com VIP Workshop 2014Road to Platform @ WordPress.com VIP Workshop 2014
Road to Platform @ WordPress.com VIP Workshop 2014Konstantin Kovshenin
 
Как повысить скорость вашего сайта на WordPress
Как повысить скорость вашего сайта на WordPressКак повысить скорость вашего сайта на WordPress
Как повысить скорость вашего сайта на WordPressKonstantin Kovshenin
 
Things I Wish I Had Known Before Developing a WordPress Theme
Things I Wish I Had Known Before Developing a WordPress ThemeThings I Wish I Had Known Before Developing a WordPress Theme
Things I Wish I Had Known Before Developing a WordPress ThemeKonstantin Kovshenin
 
7 Tips for Better WordPress Theme Development
7 Tips for Better WordPress Theme Development7 Tips for Better WordPress Theme Development
7 Tips for Better WordPress Theme DevelopmentKonstantin Kovshenin
 

More from Konstantin Kovshenin (8)

Scaling out with WordPress
Scaling out with WordPressScaling out with WordPress
Scaling out with WordPress
 
Будущее WordPress (SPB, 2014)
Будущее WordPress (SPB, 2014)Будущее WordPress (SPB, 2014)
Будущее WordPress (SPB, 2014)
 
Road to Platform @ WordPress.com VIP Workshop 2014
Road to Platform @ WordPress.com VIP Workshop 2014Road to Platform @ WordPress.com VIP Workshop 2014
Road to Platform @ WordPress.com VIP Workshop 2014
 
Будущее WordPress
Будущее WordPressБудущее WordPress
Будущее WordPress
 
Templating WordPress
Templating WordPressTemplating WordPress
Templating WordPress
 
Как повысить скорость вашего сайта на WordPress
Как повысить скорость вашего сайта на WordPressКак повысить скорость вашего сайта на WordPress
Как повысить скорость вашего сайта на WordPress
 
Things I Wish I Had Known Before Developing a WordPress Theme
Things I Wish I Had Known Before Developing a WordPress ThemeThings I Wish I Had Known Before Developing a WordPress Theme
Things I Wish I Had Known Before Developing a WordPress Theme
 
7 Tips for Better WordPress Theme Development
7 Tips for Better WordPress Theme Development7 Tips for Better WordPress Theme Development
7 Tips for Better WordPress Theme Development
 

Пожиратели памяти в WordPress