Почему мой объем памяти приложения Heroku такой большой
У меня есть приложение Rails 4.2, работающее на Heroku, Ruby версия 2.2.4
Когда я перезапускаю приложение, используя метрики времени выполнения журнала Heroku, приложение регистрирует это:
sample#memory_total=102.07MB
sample#memory_rss=102.06MB
sample#memory_cache=0.00MB
sample#memory_swap=0.00MB
sample#memory_pgpgin=29936pages
sample#memory_pgpgout=3807pages
sample#memory_quota=512.00MB
Простой щелчок на другой странице в целевом приложении сообщает об этих деталях:
sample#memory_total=267.07MB
sample#memory_rss=265.63MB
sample#memory_cache=1.43MB
sample#memory_swap=0.00MB
sample#memory_pgpgin=109878pages
sample#memory_pgpgout=41509pages
sample#memory_quota=512.00MB
Oink сообщает: использование памяти: 435416
При входе в приложение у меня есть несколько таблиц данных с нумерацией страниц, при перемещении по страницам память продолжает увеличиваться:
sample#memory_total=349.68MB
sample#memory_rss=348.18MB
sample#memory_cache=1.50MB
sample#memory_swap=0.00MB
sample#memory_pgpgin=159122pages
sample#memory_pgpgout=69604pages
sample#memory_quota=512.00MB
Отчет о расходах на данный момент: использование памяти: 602352
Если я выхожу на более простую страницу в приложении, Heroku сообщает:
sample#memory_total=353.05MB
sample#memory_rss=351.51MB
sample#memory_cache=1.54MB
sample#memory_swap=0.00MB
sample#memory_pgpgin=169306pages
sample#memory_pgpgout=78924pages
sample#memory_quota=512.00MB
Oink сообщает об использовании памяти: 604744
После 5 минут передвижения по Heroku сообщает, что объем памяти составляет от 360 до 400+ МБ. Он не попадает в ошибки Memory Quota, но если новый веб-работник будет уволен, я уверен, что так и будет.
Я также взял некоторые данные из ObjectSpace. Навигация по сайту (на этот раз по локальной сети), сначала с простейших страниц, затем ввод части с разбивкой по страницам с получением большего количества данных, выход и так далее. Вот некоторые из журналов от ObjectSpace.count_objects:
{: TOTAL => 556379,: FREE => 1142,: T_OBJECT => 27740,: T_CLASS => 7356,: T_MODULE => 1563,: T_FLOAT => 9,: T_STRING => 241807,: T_REGEXP => 2481,: T_ARRAY => 92685,: T_HASH => 16081,: T_STRUCT => 1118,: T_BIGNUM => 13,: T_FILE => 117,: T_DATA => 81408,: T_MATCH => 6132,: T_COMPLEX => 1,: T_RATIONAL = > 909,: T_SYMBOL => 1691,: T_NODE => 62347,: T_ICLASS => 11779}
{: TOTAL => 556379,: FREE => 1211,: T_OBJECT => 27540,: T_CLASS => 7354,: T_MODULE => 1565,: T_FLOAT => 9,: T_STRING => 241100,: T_REGEXP => 2478,: T_ARRAY => 93344,: T_HASH => 16763,: T_STRUCT => 1078,: T_BIGNUM => 13,: T_FILE => 122,: T_DATA => 81422,: T_MATCH => 6031,: T_COMPLEX => 1,: T_RATIONAL = > 911,: T_SYMBOL => 1690,: T_NODE => 61968,: T_ICLASS => 11779}
{: TOTAL => 556379,: FREE => 946,: T_OBJECT => 24257,: T_CLASS => 7523,: T_MODULE => 1565,: T_FLOAT => 9,: T_STRING => 251448,: T_REGEXP => 2362,: T_ARRAY => 83078,: T_HASH => 15272,: T_STRUCT => 1175,: T_BIGNUM => 63,: T_FILE => 128,: T_DATA => 89152,: T_MATCH => 5952,: T_COMPLEX => 1,: T_RATIONAL = > 963,: T_SYMBOL => 2028,: T_NODE => 58656,: T_ICLASS => 11801}
ВХОД ДАННЫХ С СТРАНИЦЕЙ, 25 ЗАПИСЕЙ НА СТРАНИЦУ, ИЗВЛЕЧЕННЫЕ ДАННЫЕ СОДЕРЖИТ УНИКАЛЬНЫЕ СТРОКИ (АДРЕСА В ФАКТЕ)
{: TOTAL => 556379,: FREE => 906,: T_OBJECT => 26280,: T_CLASS => 7363,: T_MODULE => 1563,: T_FLOAT => 9,: T_STRING => 252024,: T_REGEXP => 2474,: T_ARRAY => 87445,: T_HASH => 15347,: T_STRUCT => 1144,: T_BIGNUM => 16,: T_FILE => 133,: T_DATA => 80601,: T_MATCH => 6686,: T_COMPLEX => 1,: T_RATIONAL = > 985,: T_SYMBOL => 1690,: T_NODE => 59906,: T_ICLASS => 11806}
{: TOTAL => 556379,: FREE => 146,: T_OBJECT => 18752,: T_CLASS => 7359,: T_MODULE => 1563,: T_FLOAT => 9,: T_STRING => 295002,: T_REGEXP => 2304,: T_ARRAY => 81885,: T_HASH => 13791,: T_STRUCT => 867,: T_BIGNUM => 15,: T_FILE => 11,: T_DATA => 77634,: T_MATCH => 847,: T_COMPLEX => 1,: T_RATIONAL = > 1251,: T_SYMBOL => 1679,: T_NODE => 41463,: T_ICLASS => 11800}
{: TOTAL => 571870,: FREE => 433,: T_OBJECT => 19352,: T_CLASS => 7369,: T_MODULE => 1565,: T_FLOAT => 9,: T_STRING => 294098,: T_REGEXP => 2358,: T_ARRAY => 91079,: T_HASH => 14983,: T_STRUCT => 879,: T_BIGNUM => 15,: T_FILE => 16,: T_DATA => 77945,: T_MATCH => 1128,: T_COMPLEX => 1,: T_RATIONAL = > 1591,: T_SYMBOL => 2028,: T_NODE => 45197,: T_ICLASS => 11824}
{: TOTAL => 628109,: FREE => 343,: T_OBJECT => 20647,: T_CLASS => 7360,: T_MODULE => 1563,: T_FLOAT => 9,: T_STRING => 318169,: T_REGEXP => 2346,: T_ARRAY => 115854,: T_HASH => 17767,: T_STRUCT => 949,: T_BIGNUM => 15,: T_FILE => 10,: T_DATA => 79152,: T_MATCH => 1243,: T_COMPLEX => 1,: T_RATIONAL = > 1789,: T_SYMBOL => 1685,: T_NODE => 47405,: T_ICLASS => 11802}
{: TOTAL => 727564,: FREE => 470,: T_OBJECT => 22820,: T_CLASS => 7361,: T_MODULE => 1563,: T_FLOAT => 9,: T_STRING => 362350,: T_REGEXP => 2390,: T_ARRAY => 152959,: T_HASH => 22342,: T_STRUCT => 1035,: T_BIGNUM => 33,: T_FILE => 11,: T_DATA => 81286,: T_MATCH => 2167,: T_COMPLEX => 1,: T_RATIONAL = > 2497,: T_SYMBOL => 1686,: T_NODE => 54779,: T_ICLASS => 11805}
{: TOTAL => 811122,: FREE => 392,: T_OBJECT => 24361,: T_CLASS => 7362,: T_MODULE => 1563,: T_FLOAT => 9,: T_STRING => 409740,: T_REGEXP => 2434,: T_ARRAY => 176571,: T_HASH => 25118,: T_STRUCT => 1076,: T_BIGNUM => 51,: T_FILE => 13,: T_DATA => 82701,: T_MATCH => 2858,: T_COMPLEX => 1,: T_RATIONAL = > 3093,: T_SYMBOL => 1686,: T_NODE => 60285,: T_ICLASS => 11808}
ОСТАВЛЯЯ СЕЙЧАС БАЗЫ ДАННЫХ И СТРАНИЦЫ ДЛЯ ПРОСТОЙ СТРАНИЦЫ НА ПРИЛОЖЕНИИ
{:TOTAL=>819681,:FREE=>494,:T_OBJECT=>24601,:T_CLASS=>7374,:T_MODULE=>1563,:T_FLOAT=>9,:T_STRING=>413540,:T_REGEXP=>2437,:T_ARRAY=>178899,:T_HASH=>25953,:T_STRUCT=>1118,:T_BIGNUM=>93,:T_FILE=>14,:T_DATA=>83043,:T_MATCH=>2924,:T_COMPLEX=>1,:T_RATIONAL=>3121,:T_SYMBOL=>1688,:T_NODE=>60999,:T_ICLASS=>11810}
Я также могу получить данные gc profiler. Но что меня беспокоит, так это то, что большая часть сообщаемых данных и выделенных материалов, если они нужны из драгоценных камней, требуются и в любом случае мне нужны.
Так...
Я уже пытаюсь обнаружить утечки памяти или причину, по которой объем памяти слишком велик, и уменьшить ее настолько, насколько смогу. Любые советы, как действовать отсюда, приветствуются.
Было бы хорошо понять, почему после первого щелчка - после перезапуска - объем памяти, который сообщает Heroku, удваивается, хотя я представляю, что после этого, когда большинство объектов создаются и выделяется память.
Но тогда разница между тем, что сообщает Oink, и тем, что сообщает Heroku, огромна, я думаю, что Oink сообщает в байтах. И снова я представляю, что они сообщают о разных вещах, или, по крайней мере, Heroku сообщает о гораздо большем.
Любые хорошие советы, как интерпретировать все эти данные? Разве это не слишком большой объем памяти в 300-400 МБ для приложения Heroku?
Благодарю.
1 ответ
Я получил несколько комментариев от поддержки Heroku:
Нет ничего необычного в том, что приложение на основе Unicorn Rails занимает около 400 МБ ОЗУ. На самом деле это, вероятно, среднее значение для мастера Unicorn с предзагрузкой и двух рабочих запросов Unicorn. Это три процесса Ruby, запущенных в dyno, поэтому вам нужно быть осторожным с инструментом, который вы используете для его измерения. Метрики log-runtime-метрики будут для всего dyno, например, для всех трех процессов Ruby.
Так что это выглядит не так уж странно для моего случая. В любом случае, теперь я уделяю дополнительное внимание распределению памяти и вижу, где я могу улучшить со своей стороны.